/*
* This file is part of "JTA - Telnet/SSH for the JAVA(tm) platform".
*
* (c) Matthias L. Jugel, Marcus Meißner 1996-2005. All Rights Reserved.
*
* Please visit http://javatelnet.org/ for updates and contact.
*
* --LICENSE NOTICE--
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* --LICENSE NOTICE--
*
*/
package de.mud.jta;
import java.lang.reflect.Constructor;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;
import java.util.List;
import java.util.ArrayList;
/**
* The plugin loader tries to load the plugin by name and returns a
* corresponding plugin object. It takes care of connecting filter
* plugins
* <P>
* <B>Maintainer:</B> Matthias L. Jugel
*
* @version $Id: PluginLoader.java 499 2005-09-29 08:24:54Z leo $
* @author Matthias L. Jugel, Marcus Mei�ner
*/
public class PluginLoader implements PluginBus {
/** holds the current version id */
public final static String ID = "$Id: PluginLoader.java 499 2005-09-29 08:24:54Z leo $";
private final static int debug = 0;
/** the path to standard plugins */
private Vector PATH = null;
/** holds all the filters */
private List filter = new ArrayList();
private Map plugins;
/**
* Create new plugin loader and set up with default plugin path.
*/
public PluginLoader() {
this(null);
}
/**
* Create new plugin loader and set up with specified plugin path.
* @param path the default search path for plugins
*/
public PluginLoader(Vector path) {
plugins = new HashMap();
if (path == null) {
PATH = new Vector();
PATH.addElement("de.mud.jta.plugin");
} else
PATH = path;
}
/**
* Add a new plugin to the system and register the plugin load as its
* communication bus. If the plugin is a filter plugin and if it is
* not the first filter the last added filter will be set as its filter
* source.
* @param name the string name of the plugin
* @return the newly created plugin or null in case of an error
*/
public Plugin addPlugin(String name, String id) {
Plugin plugin = loadPlugin(name, id);
// if it was not found, try without a path as a last resort
if (plugin == null)
plugin = loadPlugin(null, name, id);
// nothing found, tell the user
if (plugin == null) {
System.err.println("plugin loader: plugin '" + name + "' was not found!");
return null;
}
// configure the filter plugins
if (plugin instanceof FilterPlugin) {
if (filter.size() > 0)
((FilterPlugin) plugin)
.setFilterSource((FilterPlugin) filter.get(filter.size() - 1));
filter.add(plugin);
}
plugins.put(name+(id == null ? "" : "(" + id + ")"), plugin);
return plugin;
}
/**
* Replace a plugin with a new one, actually reloads the plugin.
* @param name name of plugin to be replaced
* @param id unique id
* @return the newly loaded plugin
*/
public Plugin replacePlugin(String name, String id) {
Plugin plugin = loadPlugin(name, id);
if(plugin != null) {
Plugin oldPlugin = (Plugin)plugins.get(name + (id == null ? "" : "(" + id + ")"));
if(filter.contains(oldPlugin)) {
int index = filter.indexOf(oldPlugin);
filter.set(index, plugin);
((FilterPlugin)plugin).setFilterSource(((FilterPlugin)oldPlugin).getFilterSource());
if(index < filter.size() - 1) {
((FilterPlugin)filter.get(index + 1)).setFilterSource((FilterPlugin)plugin);
}
}
}
return plugin;
}
/**
* Load a plugin by cycling through the plugin path.
* @param name the class name of the plugin
* @param id an id in case of multiple plugins of the same name
* @return the loaded plugin or null if none was found
*/
private Plugin loadPlugin(String name, String id) {
Plugin plugin = null;
// cycle through the PATH to load plugin
Enumeration pathList = PATH.elements();
while (pathList.hasMoreElements()) {
String path = (String) pathList.nextElement();
plugin = loadPlugin(path, name, id);
if (plugin != null) {
return plugin;
}
}
plugin = loadPlugin(null, name, id);
return plugin;
}
/**
* Load a plugin using the specified path name and id.
* @param path the package where the plugin can be found
* @param name the class name of the plugin
* @param id an id for multiple plugins of the same name
* @return a loaded plugin or null if none was found
*/
private Plugin loadPlugin(String path, String name, String id) {
Plugin plugin = null;
String fullClassName = (path == null) ? name : path + "." + name;
// load the plugin by name and instantiate it
try {
Class c = Class.forName(fullClassName);
Constructor cc = c.getConstructor(new Class[]{PluginBus.class,
String.class});
plugin = (Plugin) cc.newInstance(new Object[]{this, id});
return plugin;
} catch (ClassNotFoundException ce) {
if (debug > 0)
System.err.println("plugin loader: plugin not found: " + fullClassName);
} catch (Exception e) {
System.err.println("plugin loader: can't load plugin: " + fullClassName);
e.printStackTrace();
}
return null;
}
/** holds the plugin listener we serve */
private Vector listener = new Vector();
/**
* Register a new plugin listener.
*/
public void registerPluginListener(PluginListener l) {
listener.addElement(l);
}
/**
* Implementation of the plugin bus. Broadcast a message to all
* listeners we know of. The message takes care that the right
* methods are called in the listeners.
* @param message the plugin message to be sent
* @return the answer to the sent message
*/
public Object broadcast(PluginMessage message) {
if (debug > 0) System.err.println("broadcast(" + message + ")");
if (message == null || listener == null)
return null;
Enumeration e = listener.elements();
Object res = null;
while (res == null && e.hasMoreElements())
res = message.firePluginMessage((PluginListener) e.nextElement());
return res;
}
public Map getPlugins() {
return plugins;
}
}