/* * Copyright(c) 2005 Center for E-Commerce Infrastructure Development, The * University of Hong Kong (HKU). All Rights Reserved. * * This software is licensed under the GNU GENERAL PUBLIC LICENSE Version 2.0 [1] * * [1] http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt */ package hk.hku.cecid.piazza.commons.spa; import java.net.URL; import java.net.URLClassLoader; import java.net.URLStreamHandlerFactory; import java.util.Iterator; import java.util.Vector; /** * A PluginClassLoader is a class loader for loading classes which * stored in the libraries specified in a plugin descriptor. * * @see Plugin * * @author Hugo Y. K. Lam * */ public class PluginClassLoader extends URLClassLoader { private Vector importedLoaders = new Vector(); private Plugin plugin; /** * Creates a new instance of PluginClassLoader. * * @param plugin the Plugin corresponds to this class loader. * @param urls the search paths. */ public PluginClassLoader(Plugin plugin, URL[] urls) { super(urls); this.plugin = plugin; } /** * Creates a new instance of PluginClassLoader. * * @param plugin the Plugin corresponds to this class loader. * @param urls the search paths. * @param parent the parent class loader. */ public PluginClassLoader(Plugin plugin, URL[] urls, ClassLoader parent) { super(urls, parent); this.plugin = plugin; } /** * Creates a new instance of PluginClassLoader. * * @param plugin the Plugin corresponds to this class loader. * @param urls the search paths. * @param parent the parent class loader. * @param factory the URL stream handler factory. */ public PluginClassLoader(Plugin plugin, URL[] urls, ClassLoader parent, URLStreamHandlerFactory factory) { super(urls, parent, factory); this.plugin = plugin; } /** * Finds and loads the class with the specified name from the URL search path. * Any URLs referring to JAR files are loaded and opened as needed until the class is found. * If the class is not found from the search paths of this class loader, it will be searched * from the imported class loaders. * * @param name the name of the class. * @return the resulting class. * @throws java.lang.ClassNotFoundException if the class could not be found. * @see java.lang.ClassLoader#findClass(java.lang.String) */ protected Class findClass(String name) throws ClassNotFoundException { try { return super.findClass(name); } catch (ClassNotFoundException e) { return findImportedClass(name); } } /** * Finds and loads the class with the specified name from the imported class loaders. * * @param name the name of the class. * @return the resulting class. * @throws java.lang.ClassNotFoundException if the class could not be found. * @see java.lang.ClassLoader#findClass(java.lang.String) */ protected Class findImportedClass(String name) throws ClassNotFoundException { Iterator loaders = importedLoaders.iterator(); while (loaders.hasNext()) { ClassLoader loader = (ClassLoader)loaders.next(); try { return loader.loadClass(name); } catch (ClassNotFoundException e) { if (loaders.hasNext()) { continue; } else { throw e; } } } throw new ClassNotFoundException("No class definition found: "+name); } /** * Imports a class loader. * * @param loader the class loader to be imported. */ void importClassLoader(ClassLoader loader) { if (loader!=null) { importedLoaders.addElement(loader); } } /** * Finds the resource with the specified name on the URL search paths. * * @param name the name of the resource. * @return a URL for the resource, or null if the resource could not be found. * @see java.lang.ClassLoader#findResource(java.lang.String) */ public URL findResource(String name) { return super.findResource(name); } /** * Gets the plugin corresponds to this class loader. * * @return the plugin corresponds to this class loader. */ public Plugin getPlugin() { return plugin; } /** * Returns a string representation of this class loader. * * @return a string representation of this class loader. * @see java.lang.Object#toString() */ public String toString() { String lf = System.getProperty("line.separator"); String ln = lf + "------------------------------" + lf; String desc = lf + "Class" + ln + this.getClass().getName() + lf + lf; desc += "Plugin" + ln + plugin + lf + lf; desc += "Classpaths" + ln; Object[] urls = super.getURLs(); for (int i = 0; i < urls.length; i++) { desc += urls[i] + lf; } desc += lf + "Imported Loaders" + ln; for (int i = 0; i < importedLoaders.size(); i++) { desc += importedLoaders.get(i) + lf; } desc += lf + "Parent" + ln + getParent(); return desc; } }