pluginmanager.java
来自「开源项目openfire的完整源程序」· Java 代码 · 共 708 行 · 第 1/2 页
JAVA
708 行
/**
* $Revision: $
* $Date: $
*
* Copyright (C) 2006 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Lesser Public License (LGPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.spark;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.jivesoftware.MainWindowListener;
import org.jivesoftware.Spark;
import org.jivesoftware.spark.plugin.Plugin;
import org.jivesoftware.spark.plugin.PluginClassLoader;
import org.jivesoftware.spark.plugin.PublicPlugin;
import org.jivesoftware.spark.util.URLFileSystem;
import org.jivesoftware.spark.util.log.Log;
import org.jivesoftware.sparkimpl.settings.JiveInfo;
import javax.swing.SwingUtilities;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipFile;
/**
* This manager is responsible for the loading of all Plugins and Workspaces within Spark environment.
*
* @author Derek DeMoro
*/
public class PluginManager implements MainWindowListener {
private final List<Plugin> plugins = new ArrayList<Plugin>();
private final List<PublicPlugin> publicPlugins = new CopyOnWriteArrayList<PublicPlugin>();
private static PluginManager singleton;
private static final Object LOCK = new Object();
/**
* The root Plugins Directory.
*/
public static File PLUGINS_DIRECTORY = new File(Spark.getBinDirectory().getParent(), "plugins").getAbsoluteFile();
private PluginClassLoader classLoader;
/**
* Returns the singleton instance of <CODE>PluginManager</CODE>,
* creating it if necessary.
* <p/>
*
* @return the singleton instance of <Code>PluginManager</CODE>
*/
public static PluginManager getInstance() {
// Synchronize on LOCK to ensure that we don't end up creating
// two singletons.
synchronized (LOCK) {
if (null == singleton) {
PluginManager controller = new PluginManager();
singleton = controller;
return controller;
}
}
return singleton;
}
private PluginManager() {
try {
PLUGINS_DIRECTORY = new File(Spark.getBinDirectory().getParentFile(), "plugins").getCanonicalFile();
}
catch (IOException e) {
Log.error(e);
}
// Do not use deployable plugins if not installed.
if (System.getProperty("plugin") == null) {
movePlugins();
}
SparkManager.getMainWindow().addMainWindowListener(this);
// Create the extension directory if one does not exist.
if (!PLUGINS_DIRECTORY.exists()) {
PLUGINS_DIRECTORY.mkdirs();
}
}
private void movePlugins() {
// Current Plugin directory
File newPlugins = new File(Spark.getLogDirectory().getParentFile(), "plugins").getAbsoluteFile();
newPlugins.mkdirs();
File[] files = PLUGINS_DIRECTORY.listFiles();
final int no = files != null ? files.length : 0;
for (int i = 0; i < no; i++) {
File file = files[i];
if (file.isFile()) {
// Copy over
File newFile = new File(newPlugins, file.getName());
if (newFile.lastModified() >= file.lastModified()) {
continue;
}
try {
URLFileSystem.copy(file.toURL(), newFile);
}
catch (IOException e) {
Log.error(e);
}
}
}
PLUGINS_DIRECTORY = newPlugins;
}
/**
* Loads all {@link Plugin} from the agent plugins.xml and extension lib.
*/
public void loadPlugins() {
// Delete all old plugins
File[] oldFiles = PLUGINS_DIRECTORY.listFiles();
final int no = oldFiles != null ? oldFiles.length : 0;
for (int i = 0; i < no; i++) {
File file = oldFiles[i];
if (file.isDirectory()) {
// Check to see if it has an associated .jar
File jarFile = new File(PLUGINS_DIRECTORY, file.getName() + ".jar");
if (!jarFile.exists()) {
uninstall(file);
}
}
}
updateClasspath();
// At the moment, the plug list is hardcode internally until I begin
// using external property files. All depends on deployment.
final URL url = getClass().getClassLoader().getResource("META-INF/plugins.xml");
try {
InputStreamReader reader = new InputStreamReader(url.openStream());
loadInternalPlugins(reader);
}
catch (IOException e) {
Log.error("Could not load plugins.xml file.");
}
// Load extension plugins
loadPublicPlugins();
// For development purposes, load the plugin specified by -Dplugin=...
String plugin = System.getProperty("plugin");
if (plugin != null) {
final StringTokenizer st = new StringTokenizer(plugin, ",", false);
while (st.hasMoreTokens()) {
String token = st.nextToken();
File pluginXML = new File(token);
loadPublicPlugin(pluginXML.getParentFile());
}
}
}
/**
* Loads public plugins.
*
* @param pluginDir the directory of the expanded public plugin.
* @return the new Plugin model for the Public Plugin.
*/
private Plugin loadPublicPlugin(File pluginDir) {
File pluginFile = new File(pluginDir, "plugin.xml");
SAXReader saxReader = new SAXReader();
Document pluginXML = null;
try {
pluginXML = saxReader.read(pluginFile);
}
catch (DocumentException e) {
Log.error(e);
}
Plugin pluginClass = null;
List plugins = pluginXML.selectNodes("/plugin");
Iterator iter = plugins.iterator();
while (iter.hasNext()) {
PublicPlugin publicPlugin = new PublicPlugin();
String clazz = null;
String name = null;
String minVersion;
String operatingSystem;
try {
Element plugin = (Element)iter.next();
name = plugin.selectSingleNode("name").getText();
clazz = plugin.selectSingleNode("class").getText();
// Check for minimum Spark version
try {
minVersion = plugin.selectSingleNode("minSparkVersion").getText();
String buildNumber = JiveInfo.getBuildNumber();
boolean ok = buildNumber.compareTo(minVersion) >= 0;
if (!ok) {
return null;
}
}
catch (Exception e) {
Log.error("Unable to load plugin " + name + " due to no minSparkVersion.");
return null;
}
// Do operating system check.
boolean operatingSystemOK = isOperatingSystemOK(plugin);
if (!operatingSystemOK) {
return null;
}
publicPlugin.setPluginClass(clazz);
publicPlugin.setName(name);
try {
String version = plugin.selectSingleNode("version").getText();
publicPlugin.setVersion(version);
String author = plugin.selectSingleNode("author").getText();
publicPlugin.setAuthor(author);
String email = plugin.selectSingleNode("email").getText();
publicPlugin.setEmail(email);
String description = plugin.selectSingleNode("description").getText();
publicPlugin.setDescription(description);
String homePage = plugin.selectSingleNode("homePage").getText();
publicPlugin.setHomePage(homePage);
}
catch (Exception e) {
Log.debug("We can ignore these.");
}
try {
pluginClass = (Plugin)getParentClassLoader().loadClass(clazz).newInstance();
Log.debug(name + " has been loaded.");
publicPlugin.setPluginDir(pluginDir);
publicPlugins.add(publicPlugin);
registerPlugin(pluginClass);
}
catch (Throwable e) {
Log.error("Unable to load plugin " + clazz + ".", e);
}
}
catch (Exception ex) {
Log.error("Unable to load plugin " + clazz + ".", ex);
}
}
return pluginClass;
}
/**
* Loads an internal plugin.
*
* @param reader the inputstreamreader for an internal plugin.
*/
private void loadInternalPlugins(InputStreamReader reader) {
SAXReader saxReader = new SAXReader();
Document pluginXML = null;
try {
pluginXML = saxReader.read(reader);
}
catch (DocumentException e) {
Log.error(e);
}
List plugins = pluginXML.selectNodes("/plugins/plugin");
Iterator iter = plugins.iterator();
while (iter.hasNext()) {
String clazz = null;
String name = null;
try {
Element plugin = (Element)iter.next();
name = plugin.selectSingleNode("name").getText();
clazz = plugin.selectSingleNode("class").getText();
Plugin pluginClass = (Plugin)Class.forName(clazz).newInstance();
Log.debug(name + " has been loaded. Internal plugin.");
registerPlugin(pluginClass);
}
catch (Throwable ex) {
Log.error("Unable to load plugin " + clazz + ".", ex);
}
}
}
private void updateClasspath() {
try {
classLoader = new PluginClassLoader(getParentClassLoader(), PLUGINS_DIRECTORY);
}
catch (MalformedURLException e) {
Log.error("Error updating classpath.", e);
}
Thread.currentThread().setContextClassLoader(classLoader);
}
/**
* Returns the plugin classloader.
*
* @return the plugin classloader.
*/
public ClassLoader getPluginClassLoader() {
return classLoader;
}
/**
* Registers a plugin.
*
* @param plugin the plugin to register.
*/
public void registerPlugin(Plugin plugin) {
plugins.add(plugin);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?