package thaw.core; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Vector; /** * Manages plugins :) */ public class PluginManager { private final static String[] defaultPlugins = { "thaw.plugins.QueueWatcher", "thaw.plugins.FetchPlugin", "thaw.plugins.InsertPlugin", "thaw.plugins.StatusBar", "thaw.plugins.ThemeSelector", "thaw.plugins.Hsqldb", "thaw.plugins.IndexBrowser", "thaw.plugins.IndexExporter", "thaw.plugins.TransferLogs" }; private final static String[] knownPlugins = { "thaw.plugins.PeerMonitor", "thaw.plugins.QueueWatcher", "thaw.plugins.FetchPlugin", "thaw.plugins.InsertPlugin", "thaw.plugins.StatusBar", "thaw.plugins.TrayIcon", "thaw.plugins.ThemeSelector", "thaw.plugins.Hsqldb", "thaw.plugins.Signatures", "thaw.plugins.WebOfTrust", "thaw.plugins.WebOfTrustViewer", "thaw.plugins.IndexBrowser", "thaw.plugins.IndexExporter", //"thaw.plugins.IndexTreeRebuilder", "thaw.plugins.MiniFrost", //"thaw.plugins.Restarter", "thaw.plugins.TransferLogs", "thaw.plugins.NodeConfigurator", "thaw.plugins.MDns", //"thaw.plugins.IndexWebGrapher", "thaw.plugins.SqlConsole", "thaw.plugins.LogConsole" }; private Core core = null; // LinkedHashMap because I want to keep a predictible plugin order. private LinkedHashMap plugins = null; // String (pluginName) -> Plugin public final static Object pluginLock = new Object(); /** * Need a ref to the core to pass it to the plugins (and to access config) */ public PluginManager(final Core core) { this.core = core; plugins = new LinkedHashMap(); } /** * Returns the whole loaded plugin list. */ public LinkedHashMap getPlugins() { return plugins; } public static String[] getKnownPlugins() { return knownPlugins; } /** * Load plugin from config or from default list. * Reload if already loaded. */ public boolean loadAndRunPlugins() { synchronized(pluginLock) { plugins = new LinkedHashMap(); Vector pluginNames; if(core.getConfig().getPluginNames().size() == 0) { Logger.notice(this, "Loading default plugin list"); /* Then we load the config with the default plugins */ for(int i = 0 ; i < PluginManager.defaultPlugins.length ; i++) { core.getConfig().addPlugin(PluginManager.defaultPlugins[i]); } } /* we duplicate the vector to avoid collisions */ /* (remember : plugins can load other plugins */ pluginNames = new Vector(core.getConfig().getPluginNames()); final Iterator pluginIt = pluginNames.iterator(); final int progressJump = (100-40) / pluginNames.size(); if (core.getSplashScreen() != null) core.getSplashScreen().setProgression(40); while(pluginIt.hasNext()) { final String pluginName = (String)pluginIt.next(); if (core.getSplashScreen() != null) core.getSplashScreen().setProgressionAndStatus(core.getSplashScreen().getProgression()+progressJump, "Loading plugin '"+pluginName.replaceFirst("thaw.plugins.", "")+"' ..."); if (loadPlugin(pluginName) == null) { Logger.notice(this, "Plugin alread loaded"); } else { runPlugin(pluginName); } } } return true; } /** * Stop all plugins. */ public boolean stopPlugins() { synchronized(pluginLock) { Iterator pluginIt; if (plugins == null) { Logger.error(this, "No plugin to stop ?!"); return false; } pluginIt = plugins.values().iterator(); while(pluginIt.hasNext()) { final Plugin plugin = (Plugin)pluginIt.next(); try { Logger.info(this, "Stopping plugin '"+plugin.getClass().getName()+"'"); if (plugin != null) plugin.stop(); else Logger.error(this, "Plugin == null !?"); } catch(final Exception e) { Logger.error(this, "Unable to stop the plugin "+ "'"+plugin.getClass().getName()+"'"+ ", because: "+e.toString()); e.printStackTrace(); } } return true; } } /** * Load a given plugin (without adding it to the config or running it). */ public Plugin loadPlugin(final String className) { synchronized(pluginLock) { Plugin plugin = null; Logger.info(this, "Loading plugin: '"+className+"'"); try { if ( plugins.get(className) != null) { Logger.debug(this, "loadPlugin(): Plugin '"+className+"' already loaded"); return null; } //Logger.info(this, "Loading plugin '"+className+"'"); plugin = (Plugin)Class.forName(className).newInstance(); plugins.put(className, plugin); } catch(final Exception e) { Logger.error(this, "loadPlugin('"+className+"'): Exception: "+e); e.printStackTrace(); return null; } return plugin; } } /** * Run a given plugin. */ public boolean runPlugin(final String className) { synchronized(pluginLock) { Logger.info(this, "Starting plugin: '"+className+"'"); try { Plugin plugin = (Plugin)plugins.get(className); javax.swing.ImageIcon icon; if (core.getSplashScreen() != null) { if ((icon = plugin.getIcon()) != null) core.getSplashScreen().addIcon(icon); else core.getSplashScreen().addIcon(thaw.gui.IconBox.add); } plugin.run(core); } catch(final Exception e) { Logger.error(this, "runPlugin('"+className+"'): Exception: "+e); e.printStackTrace(); return false; } return true; } } /** * Stop a given plugin. */ public boolean stopPlugin(final String className) { synchronized(pluginLock) { Logger.info(this, "Stopping plugin: '"+className+"'"); try { ((Plugin)plugins.get(className)).stop(); } catch(final Exception e) { Logger.error(this, "stopPlugin('"+className+"'): Exception: "+e); e.printStackTrace(); return false; } return true; } } /** * Unload a given plugin (without adding it to the config or running it). */ public boolean unloadPlugin(final String className) { synchronized(pluginLock) { try { if(plugins.get(className) == null) { Logger.notice(this, "unloadPlugin(): Plugin '"+className+"' already unloaded"); return false; } plugins.remove(className); core.getConfig().removePlugin(className); } catch(final Exception e) { Logger.error(this, "unloadPlugin('"+className+"'): Exception: "+e); e.printStackTrace(); return false; } return true; } } public Plugin getPlugin(final String className) { return (Plugin)plugins.get(className); } }