📄 pluginmanager.java
字号:
}
}
plugins.put(pluginDir.getName(), plugin);
pluginDirs.put(plugin, pluginDir);
// If this is a child plugin, register it as such.
if (parentPluginNode != null) {
String parentPlugin = parentPluginNode.getTextTrim();
List<String> childrenPlugins = parentPluginMap.get(plugins.get(parentPlugin));
if (childrenPlugins == null) {
childrenPlugins = new ArrayList<String>();
parentPluginMap.put(plugins.get(parentPlugin), childrenPlugins);
}
childrenPlugins.add(pluginDir.getName());
// Also register child to parent relationship.
childPluginMap.put(plugin, parentPlugin);
}
else {
// Only register the class loader in the case of this not being
// a child plugin.
classloaders.put(plugin, pluginLoader);
}
// Check the plugin's database schema (if it requires one).
if (!DbConnectionManager.getSchemaManager().checkPluginSchema(plugin)) {
// The schema was not there and auto-upgrade failed.
Log.error(pluginName + " - " +
LocaleUtils.getLocalizedString("upgrade.database.failure"));
System.out.println(pluginName + " - " +
LocaleUtils.getLocalizedString("upgrade.database.failure"));
}
// Load any JSP's defined by the plugin.
File webXML = new File(pluginDir, "web" + File.separator + "WEB-INF" +
File.separator + "web.xml");
if (webXML.exists()) {
PluginServlet.registerServlets(this, plugin, webXML);
}
// Load any custom-defined servlets.
File customWebXML = new File(pluginDir, "web" + File.separator + "WEB-INF" +
File.separator + "web-custom.xml");
if (customWebXML.exists()) {
PluginServlet.registerServlets(this, plugin, customWebXML);
}
if (dev != null) {
pluginDevelopment.put(plugin, dev);
}
// Init the plugin.
plugin.initializePlugin(this, pluginDir);
// If there a <adminconsole> section defined, register it.
Element adminElement = (Element)pluginXML.selectSingleNode("/plugin/adminconsole");
if (adminElement != null) {
if (parentPluginNode != null) {
pluginName = parentPluginNode.getTextTrim();
}
Element appName = (Element)adminElement.selectSingleNode(
"/plugin/adminconsole/global/appname");
if (appName != null) {
// Set the plugin name so that the proper i18n String can be loaded.
appName.addAttribute("plugin", pluginName);
}
// If global images are specified, override their URL.
Element imageEl = (Element)adminElement.selectSingleNode(
"/plugin/adminconsole/global/logo-image");
if (imageEl != null) {
imageEl.setText("plugins/" + pluginName + "/" + imageEl.getText());
// Set the plugin name so that the proper i18n String can be loaded.
imageEl.addAttribute("plugin", pluginName);
}
imageEl = (Element)adminElement.selectSingleNode("/plugin/adminconsole/global/login-image");
if (imageEl != null) {
imageEl.setText("plugins/" + pluginName + "/" + imageEl.getText());
// Set the plugin name so that the proper i18n String can be loaded.
imageEl.addAttribute("plugin", pluginName);
}
// Modify all the URL's in the XML so that they are passed through
// the plugin servlet correctly.
List urls = adminElement.selectNodes("//@url");
for (Object url : urls) {
Attribute attr = (Attribute)url;
attr.setValue("plugins/" + pluginName + "/" + attr.getValue());
}
// In order to internationalize the names and descriptions in the model,
// we add a "plugin" attribute to each tab, sidebar, and item so that
// the the renderer knows where to load the i18n Strings from.
String[] elementNames = new String [] { "tab", "sidebar", "item" };
for (String elementName : elementNames) {
List values = adminElement.selectNodes("//" + elementName);
for (Object value : values) {
Element element = (Element) value;
// Make sure there's a name or description. Otherwise, no need to
// override i18n settings.
if (element.attribute("name") != null ||
element.attribute("value") != null) {
element.addAttribute("plugin", pluginName);
}
}
}
AdminConsole.addModel(pluginName, adminElement);
}
}
else {
Log.warn("Plugin " + pluginDir + " could not be loaded: no plugin.xml file found");
}
}
catch (Throwable e) {
Log.error("Error loading plugin", e);
}
}
/**
* Unloads a plugin. The {@link Plugin#destroyPlugin()} method will be called and then
* any resources will be released. The name should be the name of the plugin directory
* and not the name as given by the plugin meta-data. This method only removes
* the plugin but does not delete the plugin JAR file. Therefore, if the plugin JAR
* still exists after this method is called, the plugin will be started again the next
* time the plugin monitor process runs. This is useful for "restarting" plugins.<p>
* <p/>
* This method is called automatically when a plugin's JAR file is deleted.
*
* @param pluginName the name of the plugin to unload.
*/
public void unloadPlugin(String pluginName) {
Log.debug("Unloading plugin " + pluginName);
Plugin plugin = plugins.get(pluginName);
if (plugin == null) {
return;
}
// Remove from dev mode if it exists.
pluginDevelopment.remove(plugin);
// See if any child plugins are defined.
if (parentPluginMap.containsKey(plugin)) {
for (String childPlugin : parentPluginMap.get(plugin)) {
Log.debug("Unloading child plugin: " + childPlugin);
unloadPlugin(childPlugin);
}
parentPluginMap.remove(plugin);
}
File webXML = new File(pluginDirectory, pluginName + File.separator + "web" + File.separator + "WEB-INF" +
File.separator + "web.xml");
if (webXML.exists()) {
AdminConsole.removeModel(pluginName);
PluginServlet.unregisterServlets(webXML);
}
File customWebXML = new File(pluginDirectory, pluginName + File.separator + "web" + File.separator + "WEB-INF" +
File.separator + "web-custom.xml");
if (customWebXML.exists()) {
PluginServlet.unregisterServlets(customWebXML);
}
// Wrap destroying the plugin in a try/catch block. Otherwise, an exception raised
// in the destroy plugin process will disrupt the whole unloading process. It's still
// possible that classloader destruction won't work in the case that destroying the plugin
// fails. In that case, Wildfire may need to be restarted to fully cleanup the plugin
// resources.
try {
plugin.destroyPlugin();
}
catch (Exception e) {
Log.error(e);
}
PluginClassLoader classLoader = classloaders.get(plugin);
// Destroy class loader if defined, which it won't be if this is a child plugin.
if (classLoader != null) {
classLoader.destroy();
}
plugins.remove(pluginName);
pluginDirs.remove(plugin);
classloaders.remove(plugin);
// 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);
}
/**
* 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.
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -