001: /*
002: * Lucane - a collaborative platform
003: * Copyright (C) 2002 Vincent Fiack <vfiack@mail15.com>
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: */
019: package org.lucane.client;
020:
021: import org.lucane.common.*;
022: import org.lucane.common.net.ObjectConnection;
023:
024: import java.net.URL;
025: import java.util.*;
026:
027: /**
028: * This is an important part of the Client.
029: * It can dynamically load plugins.
030: */
031: public class PluginManager {
032: private static PluginManager instance = null;
033:
034: //stores available plugins in a (name, plugin) map
035: private HashMap availablePlugins;
036:
037: //stores running plugins
038: private ArrayList runningPlugins;
039:
040: /**
041: * PluginManager is a singleton
042: *
043: * @return the unique PluginManager instance
044: */
045: public static PluginManager getInstance() {
046: if (instance == null)
047: instance = new PluginManager();
048:
049: return instance;
050: }
051:
052: /**
053: * Creates a PluginManager and initialize its plugins list
054: */
055: private PluginManager() {
056: this .availablePlugins = new HashMap();
057: this .runningPlugins = new ArrayList();
058: }
059:
060: //-- plugin initialization & run
061:
062: /**
063: * Get a new plugin instance
064: *
065: * @param name the plugin name
066: * @param friends the connectinfos
067: * @param starter true if the plugin is starter
068: * @return a new plugin instance
069: */
070: public Plugin newPluginInstance(String name, ConnectInfo[] friends,
071: boolean starter) {
072: Plugin base = (Plugin) this .availablePlugins.get(name);
073: Plugin p = base.newInstance(friends);
074: p.setStarter(starter);
075: p.setName(base.getName());
076: p.setLocale(Client.getInstance().getConfig().getLanguage());
077:
078: return p;
079: }
080:
081: /**
082: * Loads a Plugin.
083: * Initialize it with the correct streams and run it in a new Thread
084: *
085: * @param oc the ObjectConnection
086: * @param message the message
087: */
088: public Plugin load(ObjectConnection oc, Message message) {
089: String name = message.getApplication();
090: Logging.getLogger().fine("Trying to load plugin " + name);
091:
092: Plugin p = newPluginInstance(name, new ConnectInfo[0], false);
093: p.setStarter(false);
094: p.load(oc, message.getSender(), (String) message.getData());
095: (new Thread(p, p.getName())).start();
096: Logging.getLogger().info("Plugin " + name + " loaded.");
097: return p;
098: }
099:
100: /**
101: * Runs the requested Plugin in a new Thread
102: *
103: * @param name the Plugin to run
104: * @param friends the connexions associated with the plugin
105: */
106: public Plugin run(String name, ConnectInfo[] friends) {
107: Logging.getLogger().fine("Trying to run plugin " + name);
108: Plugin p = newPluginInstance(name, friends, true);
109: p.setStarter(true);
110: (new Thread(p, p.getName())).start();
111: Logging.getLogger().fine("Plugin " + name + " started.");
112:
113: return p;
114: }
115:
116: //-- available plugins
117:
118: /**
119: * Check if a Plugin is available
120: *
121: * @param name the Plugin to check
122: * @return true if the client has this Plugin
123: */
124: public boolean isAvailable(String name) {
125: return this .isAvailable(name, "", false);
126: }
127:
128: /**
129: * Check if a Plugin is available
130: *
131: * @param name the Plugin to check
132: * @param version the version to check
133: * @return true if the Client has this version of the Plugin
134: */
135: public boolean isAvailable(String name, String version) {
136: return isAvailable(name, version, false);
137: }
138:
139: /**
140: * Check if a Plugin is available
141: *
142: * @param name the Plugin to check
143: * @param version the version to check
144: * @param load trus if the PluginManager has to load the Plugin
145: * @return true if the Client has this version of the Plugin
146: */
147: protected boolean isAvailable(String name, String version,
148: boolean load) {
149: Plugin plugin;
150: if (load == true) {
151: try {
152: LucaneClassLoader loader = LucaneClassLoader
153: .getInstance();
154: String baseURL = System.getProperty("user.dir") + "/"
155: + Client.APPLICATIONS_DIRECTORY;
156: String jarUrl = baseURL + name + ".jar";
157: URL url = new URL("jar:file:///" + jarUrl + "!/");
158: loader.addUrl(url);
159: Logging.getLogger().fine("plugin URL: " + url);
160:
161: //we have to set our ClassLoader to reload the plugin.
162: String className = JarUtils.getPluginClass(jarUrl);
163: Logging.getLogger().finer("classname: " + className);
164:
165: plugin = (Plugin) Class
166: .forName(className, true, loader).newInstance();
167: plugin.setName(name);
168: plugin.setLocale(Client.getInstance().getConfig()
169: .getLanguage());
170: this .availablePlugins.put(plugin.getName(), plugin);
171: Logging.getLogger().info(
172: "Loaded plugin " + plugin.getName() + " v. "
173: + plugin.getVersion());
174: } catch (Exception e) {
175: return false;
176: }
177: }
178:
179: plugin = (Plugin) this .availablePlugins.get(name);
180: return plugin != null
181: && (plugin.getVersion().equals(version) || version
182: .length() == 0);
183: }
184:
185: /**
186: * Get all available plugins
187: *
188: * @return an iterator
189: */
190: public Iterator getAvailablePlugins() {
191: return this .availablePlugins.values().iterator();
192: }
193:
194: /**
195: * Get a plugin by its name
196: *
197: * @param name the plugin name
198: * @return the corresponding Plugin
199: */
200: public Plugin getPlugin(String name) {
201: return (Plugin) this .availablePlugins.get(name);
202: }
203:
204: //-- running plugins
205:
206: /**
207: * Tells the client that a plugin has been launched.
208: */
209: protected void addRunningPlugin(Plugin p) {
210: Logging.getLogger().fine("registering : " + p.getName());
211: this .runningPlugins.add(p);
212: }
213:
214: /**
215: * Tells a client that a plugin has been closed.
216: */
217: protected void removeRunningPlugin(Plugin p) {
218: Logging.getLogger().fine("unregistering : " + p.getName());
219: this .runningPlugins.remove(p);
220:
221: //if no more plugins are running, or if we quit the startup plugin,
222: //exits the client cleanly
223: if (runningPlugins.isEmpty()
224: || p.getName().equals(
225: Client.getInstance().getStartupPlugin()))
226: Client.getInstance().cleanExit();
227: }
228:
229: /**
230: * Get plugins that are currently running
231: *
232: * @return an iterator containing active plugins
233: */
234: public Iterator getRunningPlugins() {
235: return runningPlugins.iterator();
236: }
237: }
|