📄 pluginmanager.java
字号:
// plugin are still in memory.
File dir = new File(pluginDirectory, pluginName);
// Give the plugin 2 seconds to unload.
try {
Thread.sleep(2000);
// Ask the system to clean up references.
System.gc();
int count = 0;
while (!deleteDir(dir) && count < 5) {
Log.warn("Error unloading plugin " + pluginName + ". " + "Will attempt again momentarily.");
Thread.sleep(8000);
count++;
// Ask the system to clean up references.
System.gc();
}
} catch (InterruptedException e) {
Log.error(e);
}
if (plugin != null && !dir.exists()) {
// Unregister plugin caches
PluginCacheRegistry.getInstance().unregisterCaches(pluginName);
// See if this is a child plugin. If it is, we should unload
// the parent plugin as well.
if (childPluginMap.containsKey(plugin)) {
unloadPlugin(childPluginMap.get(plugin));
}
childPluginMap.remove(plugin);
firePluginDestroyedEvent(pluginName, plugin);
}
else if (plugin != null) {
// Restore references since we failed to remove the plugin
plugins.put(pluginName, plugin);
pluginDirs.put(plugin, pluginFile);
classloaders.put(plugin, pluginLoader);
}
}
private void firePluginDestroyedEvent(String name, Plugin plugin) {
for (PluginListener listener : pluginListeners) {
listener.pluginDestroyed(name, plugin);
}
}
/**
* Loads a class from the classloader of a plugin.
*
* @param plugin the plugin.
* @param className the name of the class to load.
* @return the class.
* @throws ClassNotFoundException if the class was not found.
* @throws IllegalAccessException if not allowed to access the class.
* @throws InstantiationException if the class could not be created.
*/
public Class loadClass(Plugin plugin, String className) throws ClassNotFoundException,
IllegalAccessException, InstantiationException {
PluginClassLoader loader = classloaders.get(plugin);
return loader.loadClass(className);
}
/**
* Returns a plugin's dev environment if development mode is enabled for
* the plugin.
*
* @param plugin the plugin.
* @return the plugin dev environment, or <tt>null</tt> if development
* mode is not enabled for the plugin.
*/
public PluginDevEnvironment getDevEnvironment(Plugin plugin) {
return pluginDevelopment.get(plugin);
}
/**
* Returns the name of a plugin. The value is retrieved from the plugin.xml file
* of the plugin. If the value could not be found, <tt>null</tt> will be returned.
* Note that this value is distinct from the name of the plugin directory.
*
* @param plugin the plugin.
* @return the plugin's name.
*/
public String getName(Plugin plugin) {
String name = getElementValue(plugin, "/plugin/name");
String pluginName = pluginDirs.get(plugin).getName();
if (name != null) {
return AdminConsole.getAdminText(name, pluginName);
}
else {
return pluginName;
}
}
/**
* Returns the description of a plugin. The value is retrieved from the plugin.xml file
* of the plugin. If the value could not be found, <tt>null</tt> will be returned.
*
* @param plugin the plugin.
* @return the plugin's description.
*/
public String getDescription(Plugin plugin) {
String pluginName = pluginDirs.get(plugin).getName();
return AdminConsole.getAdminText(getElementValue(plugin, "/plugin/description"), pluginName);
}
/**
* Returns the author of a plugin. The value is retrieved from the plugin.xml file
* of the plugin. If the value could not be found, <tt>null</tt> will be returned.
*
* @param plugin the plugin.
* @return the plugin's author.
*/
public String getAuthor(Plugin plugin) {
return getElementValue(plugin, "/plugin/author");
}
/**
* Returns the version of a plugin. The value is retrieved from the plugin.xml file
* of the plugin. If the value could not be found, <tt>null</tt> will be returned.
*
* @param plugin the plugin.
* @return the plugin's version.
*/
public String getVersion(Plugin plugin) {
return getElementValue(plugin, "/plugin/version");
}
/**
* Returns the minimum server version this plugin can run within. The value is retrieved from the plugin.xml file
* of the plugin. If the value could not be found, <tt>null</tt> will be returned.
*
* @param plugin the plugin.
* @return the plugin's version.
*/
public String getMinServerVersion(Plugin plugin) {
return getElementValue(plugin, "/plugin/minServerVersion");
}
/**
* Returns the database schema key of a plugin, if it exists. The value is retrieved
* from the plugin.xml file of the plugin. If the value could not be found, <tt>null</tt>
* will be returned.
*
* @param plugin the plugin.
* @return the plugin's database schema key or <tt>null</tt> if it doesn't exist.
*/
public String getDatabaseKey(Plugin plugin) {
return getElementValue(plugin, "/plugin/databaseKey");
}
/**
* Returns the database schema version of a plugin, if it exists. The value is retrieved
* from the plugin.xml file of the plugin. If the value could not be found, <tt>-1</tt>
* will be returned.
*
* @param plugin the plugin.
* @return the plugin's database schema version or <tt>-1</tt> if it doesn't exist.
*/
public int getDatabaseVersion(Plugin plugin) {
String versionString = getElementValue(plugin, "/plugin/databaseVersion");
if (versionString != null) {
try {
return Integer.parseInt(versionString.trim());
}
catch (NumberFormatException nfe) {
Log.error(nfe);
}
}
return -1;
}
/**
* Returns the license agreement type that the plugin is governed by. The value
* is retrieved from the plugin.xml file of the plugin. If the value could not be
* found, {@link License#other} is returned.
*
* @param plugin the plugin.
* @return the plugin's license agreement.
*/
public License getLicense(Plugin plugin) {
String licenseString = getElementValue(plugin, "/plugin/licenseType");
if (licenseString != null) {
try {
// Attempt to load the get the license type. We lower-case and
// trim the license type to give plugin author's a break. If the
// license type is not recognized, we'll log the error and default
// to "other".
return License.valueOf(licenseString.toLowerCase().trim());
}
catch (IllegalArgumentException iae) {
Log.error(iae);
}
}
return License.other;
}
/**
* Returns the classloader of a plugin.
*
* @param plugin the plugin.
* @return the classloader of the plugin.
*/
public PluginClassLoader getPluginClassloader(Plugin plugin) {
return classloaders.get(plugin);
}
/**
* Returns the value of an element selected via an xpath expression from
* a Plugin's plugin.xml file.
*
* @param plugin the plugin.
* @param xpath the xpath expression.
* @return the value of the element selected by the xpath expression.
*/
private String getElementValue(Plugin plugin, String xpath) {
File pluginDir = pluginDirs.get(plugin);
if (pluginDir == null) {
return null;
}
try {
File pluginConfig = new File(pluginDir, "plugin.xml");
if (pluginConfig.exists()) {
SAXReader saxReader = new SAXReader();
saxReader.setEncoding("UTF-8");
Document pluginXML = saxReader.read(pluginConfig);
Element element = (Element)pluginXML.selectSingleNode(xpath);
if (element != null) {
return element.getTextTrim();
}
}
}
catch (Exception e) {
Log.error(e);
}
return null;
}
/**
* An enumberation for plugin license agreement types.
*/
@SuppressWarnings({"UnnecessarySemicolon"}) // Support for QDox Parser
public enum License {
/**
* The plugin is distributed using a commercial license.
*/
commercial,
/**
* The plugin is distributed using the GNU Public License (GPL).
*/
gpl,
/**
* The plugin is distributed using the Apache license.
*/
apache,
/**
* The plugin is for internal use at an organization only and is not re-distributed.
*/
internal,
/**
* The plugin is distributed under another license agreement not covered by
* one of the other choices. The license agreement should be detailed in the
* plugin Readme.
*/
other;
}
/**
* A service that monitors the plugin directory for plugins. It periodically
* checks for new plugin JAR files and extracts them if they haven't already
* been extracted. Then, any new plugin directories are loaded.
*/
private class PluginMonitor implements Runnable {
/**
* Tracks if the monitor is currently running.
*/
private boolean running = false;
/**
* True if the monitor has been executed at least once. After the first iteration in {@link #run}
* this variable will always be true.
* */
private boolean executed = false;
/**
* True when it's the first time the plugin monitor process runs. This is helpful for
* bootstrapping purposes.
*/
private boolean firstRun = true;
public void run() {
// If the task is already running, return.
synchronized (this) {
if (running) {
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -