📄 pluginmanager.java
字号:
/*
* SSL-Explorer
*
* Copyright (C) 2003-2006 3SP LTD. All Rights Reserved
*
* 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.
*/
package com.sslexplorer.plugin;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.Vector;
import java.util.prefs.Preferences;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.sslexplorer.boot.ContextHolder;
import com.sslexplorer.boot.Util;
import com.sslexplorer.boot.VersionInfo;
import com.sslexplorer.core.CoreServlet;
import com.sslexplorer.core.CoreUtil;
public class PluginManager {
public final static Preferences PREF = ContextHolder.getContext().getPreferences().node("plugin");
public final static Log log = LogFactory.getLog(PluginManager.class);
// Plugin status
public final static int STATUS_UNINITIALIZED = 0;
public final static int STATUS_STARTED = 1;
public final static int STATUS_STOPPED = 2;
public final static int STATUS_ERRORED = 3;
// Private instance variables
private ClassLoader classLoader;
private List pluginDefinitions;
private HashMap pluginDefinitionMap;
private List plugins;
private HashMap pluginMap;
private boolean stopping;
public PluginManager() {
pluginDefinitions = new ArrayList();
pluginDefinitionMap = new HashMap();
plugins = new ArrayList();
pluginMap = new HashMap();
}
public void addPluginDefinition(PluginDefinition def) throws IllegalArgumentException {
PluginDefinition oldDef = (PluginDefinition) pluginDefinitionMap.get(def.getDescriptor().getId());
if (oldDef != null) {
pluginDefinitions.remove(oldDef);
}
pluginDefinitions.add(def);
pluginDefinitionMap.put(def.getDescriptor().getId(), def);
Collections.sort(pluginDefinitions);
}
public void init() throws PluginException {
// Add the plugins to the classpath (unless in dev mode)
if ("true".equals(System.getProperty("sslexplorer.forceAddPluginClasspath")) || !"true".equalsIgnoreCase(System.getProperty("sslexplorer.useDevConfig", "false"))) {
for (Iterator i = pluginDefinitions.iterator(); i.hasNext();) {
PluginDefinition def = (PluginDefinition) i.next();
for (Iterator j = def.getClassPath().iterator(); j.hasNext();) {
URL u = (URL) j.next();
ContextHolder.getContext().addContextLoaderURL(u);
}
for (Iterator j = def.getNativeDirectories(); j.hasNext();) {
File f = (File) j.next();
try {
CoreUtil.addLibraryPath(f.getAbsolutePath());
} catch (IOException e) {
log.error("Failed to add native directory " + f.getAbsolutePath() + ". The plugin " + def.getName()
+ " may not function correctly.", e);
}
}
}
} else {
log.warn("Running in development mode, so not adding plugin jars to the classpath or native libraries to "
+ "the library path (you must do this yourself when launching)");
}
// Add any additional class path elements
StringTokenizer t = new StringTokenizer(System.getProperty("sslexplorer.additionalClasspath", ""), ",");
while (t.hasMoreTokens()) {
try {
String sf = t.nextToken();
File[] f = null;
if(sf.endsWith("/*.jar")) {
f = new File(sf.substring(0, sf.length() - 6)).listFiles(new FileFilter() {
public boolean accept(File pathname) {
return pathname.getName().toLowerCase().endsWith(".jar");
}
});
}
else {
f = new File[1];
f[0] = new File(sf);
}
for(int j = 0 ; f != null && j < f.length; j++) {
if (f[j].exists() && (f[j].isDirectory() || f[j].getName().toLowerCase().endsWith(".jar"))) {
URL u = f[j].toURL();
ContextHolder.getContext().addContextLoaderURL(u);
}
}
} catch (MalformedURLException murle) {
log.warn("Invalid element in additional classpaths");
}
}
// Load the plugins and check dependencies
try {
loadPlugins();
checkDependencies();
} catch (Throwable ex) {
throw new PluginException("Plugin manager failed to initialise. ", ex);
}
}
public void loadPlugins() throws PluginException {
InputStream in = null;
try {
for (Iterator i = pluginDefinitions.iterator(); i.hasNext();) {
PluginDefinition def = (PluginDefinition) i.next();
if (log.isInfoEnabled())
log.info("Loading plugin " + def.getDescriptor().getId());
try {
PluginVersion reqVersion = null;
if (!def.getRequiredHostVersion().equalsIgnoreCase("any")) {
PluginVersion hostVersion = new PluginVersion(VersionInfo.getVersion().toString());
reqVersion = new PluginVersion(def.getRequiredHostVersion());
int dif = reqVersion.compareTo(hostVersion);
if (dif > 0)
throw new PluginException("This plugin requires that SSL-Explorer is at least of version "
+ reqVersion.toString());
}
ClassLoader cl = Thread.currentThread().getContextClassLoader();
if (cl == null) {
cl = getClass().getClassLoader();
}
Plugin plugin = (Plugin) Class.forName(def.getClassName(), true, cl).newInstance();
String resn = plugin.getClass().getName().replace('.', '/') + ".class";
if (log.isDebugEnabled())
log.debug("Looking for resource " + resn);
URL res = plugin.getClass().getClassLoader().getResource(resn);
String resource = "";
if (res == null)
log.error("Could not locate resource " + resn);
else {
String n = res.toExternalForm();
if (n.startsWith("jar:file:")) {
n = n.substring(4);
int idx = n.lastIndexOf('!');
if (idx != -1)
n = n.substring(0, idx);
n = n.substring(5);
// Windows path?
if (n.startsWith("/") && n.length() > 3 && n.charAt(2) == ':' && Character.isLetter(n.charAt(1))
&& n.charAt(3) == '/')
n = n.substring(1);
File f = new File(n);
resource = f.getAbsolutePath();
}
if (log.isDebugEnabled())
log.debug("Resource is " + resource);
}
plugins.add(plugin);
pluginMap.put(def.getDescriptor().getId(), plugin);
} catch (Throwable t) {
log.error("Failed to load plugin " + def.getClassName(), t);
}
}
} finally {
PluginUtil.closeStream(in);
}
Collections.sort(plugins, new Comparator() {
public int compare(Object arg0, Object arg1) {
Plugin p0 = (Plugin) arg0;
Plugin p1 = (Plugin) arg1;
PluginDefinition def0 = getPluginDefinition(p0);
PluginDefinition def1 = getPluginDefinition(p1);
return def0.compareTo(def1);
}
});
}
private void checkDependencies() {
List toRemove = new ArrayList();
for (Iterator i = pluginDefinitions.iterator(); i.hasNext();) {
PluginDefinition w = (PluginDefinition) i.next();
if (log.isInfoEnabled())
log.info("Checking dependencies for " + w.getDescriptor().getId() + " (order " + w.getOrder() + ")");
String deps = w.getDependencies();
if (deps != null) {
if (log.isInfoEnabled())
log.info("Dependencies for " + w.getDescriptor().getId() + " are " + deps);
StringTokenizer t = new StringTokenizer(deps, ",");
while (t.hasMoreTokens()) {
String depName = t.nextToken();
int idx = depName.indexOf("/");
PluginVersion reqDepVersion = null;
if (idx != -1) {
String depVersionText = depName.substring(idx + 1);
if (depVersionText.length() > 0) {
reqDepVersion = new PluginVersion(depVersionText);
}
depName = depName.substring(0, idx);
}
// First check the plugin exists
PluginDefinition dep = getPluginDefinition(depName);
if (dep == null) {
log.error("Plugin " + w.getDescriptor().getId() + " depends on " + depName + " "
+ (reqDepVersion == null ? "" : ("(version " + reqDepVersion.toString() + ") "))
+ "which is not installed. This plugin will not be loaded");
toRemove.add(w);
} else {
// Now check the version if correct (if required)
if (reqDepVersion != null) {
PluginVersion depVersion = new PluginVersion(dep.getDescriptor().getApplicationBundle().getVersion()
.toString());
if (depVersion.compareTo(reqDepVersion) < 0) {
log.error("Plugin " + w.getDescriptor().getId() + " depends on " + depName + " (version "
+ reqDepVersion.toString() + "), but only version " + depVersion
+ " is installed. Please upgrade the dependency");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -