use of org.jivesoftware.util.Version in project Openfire by igniterealtime.
the class BookmarksPlugin method checkForIncompatibleClientControlPlugin.
/**
* Checks if there's a plugin named "clientControl" in the Openfire plugin directory of which the version is equal
* to or earlier than 1.3.1.
*
* @return true if the clientControl plugin (<= 1.3.1) is found, otherwise false.
*/
private static boolean checkForIncompatibleClientControlPlugin() throws IOException, DocumentException {
final JarFile jar = getPluginJar("clientControl");
if (jar == null) {
return false;
}
final ZipEntry pluginXml = jar.getEntry("plugin.xml");
if (pluginXml == null) {
// Odd - not a plugin?
Log.warn("Found a clientControl.jar file that does not appear to include a plugin.xml.", jar.getName());
return false;
}
final File tempFile = File.createTempFile("plugin-xml", "xml");
try (final InputStream is = jar.getInputStream(pluginXml);
final FileOutputStream os = new FileOutputStream(tempFile)) {
while (is.available() > 0) {
os.write(is.read());
}
final SAXReader saxReader = new SAXReader();
saxReader.setEncoding("UTF-8");
final Document pluginXML = saxReader.read(tempFile);
Element element = (Element) pluginXML.selectSingleNode("/plugin/version");
if (element != null) {
final Version version = new Version(element.getTextTrim());
return !version.isNewerThan(new Version("1.3.1"));
}
}
return false;
}
use of org.jivesoftware.util.Version in project Openfire by igniterealtime.
the class PluginManager method loadPlugin.
/**
* Loads a plugin.
*
* @param pluginDir the plugin directory.
*/
boolean loadPlugin(Path pluginDir) {
// Only load the admin plugin during setup mode.
final String pluginName = pluginDir.getFileName().toString();
if (XMPPServer.getInstance().isSetupMode() && !(pluginName.equals("admin"))) {
return false;
}
if (failureToLoadCount.containsKey(pluginName) && failureToLoadCount.get(pluginName) > JiveGlobals.getIntProperty("plugins.loading.retries", 5)) {
Log.debug("The unloaded file for plugin '{}' is silently ignored, as it has failed to load repeatedly.", pluginName);
return false;
}
Log.debug("Loading plugin '{}'...", pluginName);
try {
final Path pluginConfig = pluginDir.resolve("plugin.xml");
if (!Files.exists(pluginConfig)) {
Log.warn("Plugin '{}' could not be loaded: no plugin.xml file found.", pluginName);
// Don't retry - this cannot be recovered from.
failureToLoadCount.put(pluginName, Integer.MAX_VALUE);
return false;
}
final SAXReader saxReader = new SAXReader();
saxReader.setEncoding("UTF-8");
final Document pluginXML = saxReader.read(pluginConfig.toFile());
// See if the plugin specifies a version of Openfire required to run.
final Element minServerVersion = (Element) pluginXML.selectSingleNode("/plugin/minServerVersion");
if (minServerVersion != null) {
final Version requiredVersion = new Version(minServerVersion.getTextTrim());
final Version currentVersion = XMPPServer.getInstance().getServerInfo().getVersion();
if (requiredVersion.isNewerThan(currentVersion)) {
Log.warn("Ignoring plugin '{}': requires server version {}. Current server version is {}.", pluginName, requiredVersion, currentVersion);
// Don't retry - this cannot be recovered from.
failureToLoadCount.put(pluginName, Integer.MAX_VALUE);
return false;
}
}
// Properties to be used to load external resources. When set, plugin is considered to run in DEV mode.
final String devModeClassesDir = System.getProperty(pluginName + ".classes");
final String devModewebRoot = System.getProperty(pluginName + ".webRoot");
final boolean devMode = devModewebRoot != null || devModeClassesDir != null;
final PluginDevEnvironment dev = (devMode ? configurePluginDevEnvironment(pluginDir, devModeClassesDir, devModewebRoot) : null);
// Initialize the plugin class loader, which is either a new instance, or a the loader from a parent plugin.
final PluginClassLoader pluginLoader;
// Check to see if this is a child plugin of another plugin. If it is, we re-use the parent plugin's class
// loader so that the plugins can interact.
String parentPluginName = null;
Plugin parentPlugin = null;
final Element parentPluginNode = (Element) pluginXML.selectSingleNode("/plugin/parentPlugin");
if (parentPluginNode != null) {
// The name of the parent plugin as specified in plugin.xml might have incorrect casing. Lookup the correct name.
for (final Map.Entry<String, Plugin> entry : plugins.entrySet()) {
if (entry.getKey().equalsIgnoreCase(parentPluginNode.getTextTrim())) {
parentPluginName = entry.getKey();
parentPlugin = entry.getValue();
break;
}
}
// See if the parent is loaded.
if (parentPlugin == null) {
Log.info("Unable to load plugin '{}': parent plugin '{}' has not been loaded.", pluginName, parentPluginNode.getTextTrim());
Integer count = failureToLoadCount.get(pluginName);
if (count == null) {
count = 0;
}
failureToLoadCount.put(pluginName, ++count);
return false;
}
pluginLoader = classloaders.get(parentPlugin);
} else {
// This is not a child plugin, so create a new class loader.
pluginLoader = new PluginClassLoader();
}
// Add the plugin sources to the classloaded.
pluginLoader.addDirectory(pluginDir.toFile(), devMode);
// When running in DEV mode, add optional other sources too.
if (dev != null && dev.getClassesDir() != null) {
pluginLoader.addURLFile(dev.getClassesDir().toURI().toURL());
}
// Instantiate the plugin!
final String className = pluginXML.selectSingleNode("/plugin/class").getText().trim();
final Plugin plugin = (Plugin) pluginLoader.loadClass(className).newInstance();
// Bookkeeping!
classloaders.put(plugin, pluginLoader);
plugins.put(pluginName, plugin);
pluginDirs.put(plugin, pluginDir);
if (dev != null) {
pluginDevelopment.put(plugin, dev);
}
// If this is a child plugin, register it as such.
if (parentPlugin != null) {
List<String> childrenPlugins = parentPluginMap.get(parentPlugin);
if (childrenPlugins == null) {
childrenPlugins = new ArrayList<>();
parentPluginMap.put(parentPlugin, childrenPlugins);
}
childrenPlugins.add(pluginName);
// Also register child to parent relationship.
childPluginMap.put(plugin, parentPluginName);
}
// 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("Error while loading plugin '{}': {}", pluginName, LocaleUtils.getLocalizedString("upgrade.database.failure"));
}
// Load any JSP's defined by the plugin.
final Path webXML = pluginDir.resolve("web").resolve("WEB-INF").resolve("web.xml");
if (Files.exists(webXML)) {
PluginServlet.registerServlets(this, plugin, webXML.toFile());
}
// Load any custom-defined servlets.
final Path customWebXML = pluginDir.resolve("web").resolve("WEB-INF").resolve("web-custom.xml");
if (Files.exists(customWebXML)) {
PluginServlet.registerServlets(this, plugin, customWebXML.toFile());
}
// Configure caches of the plugin
configureCaches(pluginDir, pluginName);
// Initialze the plugin.
final ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(pluginLoader);
plugin.initializePlugin(this, pluginDir.toFile());
Log.debug("Initialized plugin '{}'.", pluginName);
Thread.currentThread().setContextClassLoader(oldLoader);
// If there a <adminconsole> section defined, register it.
final Element adminElement = (Element) pluginXML.selectSingleNode("/plugin/adminconsole");
if (adminElement != null) {
final 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.
final List urls = adminElement.selectNodes("//@url");
for (final Object url : urls) {
final 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.
final String[] elementNames = new String[] { "tab", "sidebar", "item" };
for (final String elementName : elementNames) {
final List values = adminElement.selectNodes("//" + elementName);
for (final Object value : values) {
final Element element = (Element) value;
// Make sure there's a name or description. Otherwise, no need to i18n settings.
if (element.attribute("name") != null || element.attribute("value") != null) {
element.addAttribute("plugin", pluginName);
}
}
}
AdminConsole.addModel(pluginName, adminElement);
}
firePluginCreatedEvent(pluginName, plugin);
Log.info("Successfully loaded plugin '{}'.", pluginName);
return true;
} catch (Throwable e) {
Log.error("An exception occurred while loading plugin '{}':", pluginName, e);
Integer count = failureToLoadCount.get(pluginName);
if (count == null) {
count = 0;
}
failureToLoadCount.put(pluginName, ++count);
return false;
}
}
use of org.jivesoftware.util.Version in project Openfire by igniterealtime.
the class AvailablePlugin method getInstance.
public static AvailablePlugin getInstance(Element plugin) {
String pluginName = plugin.attributeValue("name");
Version latestVersion = null;
String latestVersionValue = plugin.attributeValue("latest");
if (latestVersionValue != null && !latestVersionValue.isEmpty()) {
latestVersion = new Version(latestVersionValue);
}
URL icon = null;
String iconValue = plugin.attributeValue("icon");
if (iconValue != null && !iconValue.isEmpty()) {
try {
icon = new URL(iconValue);
} catch (MalformedURLException e) {
Log.warn("Unable to create icon URL from value '{}' for plugin {}.", iconValue, pluginName, e);
}
}
URL readme = null;
String readmeValue = plugin.attributeValue("readme");
if (readmeValue != null && !readmeValue.isEmpty()) {
try {
readme = new URL(readmeValue);
} catch (MalformedURLException e) {
Log.warn("Unable to create readme URL from value '{}' for plugin {}.", readmeValue, pluginName, e);
}
}
URL changelog = null;
String changelogValue = plugin.attributeValue("changelog");
if (changelogValue != null && !changelogValue.isEmpty()) {
try {
changelog = new URL(changelogValue);
} catch (MalformedURLException e) {
Log.warn("Unable to create changelog URL from value '{}' for plugin {}.", changelogValue, pluginName, e);
}
}
URL downloadUrl = null;
String downloadUrlValue = plugin.attributeValue("url");
if (downloadUrlValue != null && !downloadUrlValue.isEmpty()) {
try {
downloadUrl = new URL(downloadUrlValue);
} catch (MalformedURLException e) {
Log.warn("Unable to create download URL from value '{}' for plugin {}.", downloadUrlValue, pluginName, e);
}
}
String license = plugin.attributeValue("licenseType");
String description = plugin.attributeValue("description");
String author = plugin.attributeValue("author");
Version minServerVersion = null;
String minServerVersionValue = plugin.attributeValue("minServerVersion");
if (minServerVersionValue != null && !minServerVersionValue.isEmpty()) {
minServerVersion = new Version(minServerVersionValue);
}
Version priorToServerVersion = null;
String priorToServerVersionValue = plugin.attributeValue("priorToServerVersion");
if (priorToServerVersionValue != null && !priorToServerVersionValue.isEmpty()) {
priorToServerVersion = new Version(priorToServerVersionValue);
}
JavaSpecVersion minJavaVersion = null;
String minJavaVersionValue = plugin.attributeValue("minJavaVersion");
if (minJavaVersionValue != null && !minJavaVersionValue.isEmpty()) {
minJavaVersion = new JavaSpecVersion(minJavaVersionValue);
}
String releaseDate = null;
final String releaseDateString = plugin.attributeValue("releaseDate");
if (releaseDateString != null) {
try {
releaseDate = RELEASE_DATE_DISPLAY_FORMAT.format(RELEASE_DATE_FORMAT.parse(releaseDateString));
} catch (final ParseException e) {
Log.warn("Unexpected exception parsing release date: " + releaseDateString, e);
}
}
long fileSize = -1;
String fileSizeValue = plugin.attributeValue("fileSize");
if (fileSizeValue != null && !fileSizeValue.isEmpty()) {
fileSize = Long.parseLong(fileSizeValue);
}
String canonical = downloadUrlValue != null ? downloadUrlValue.substring(downloadUrlValue.lastIndexOf('/') + 1, downloadUrlValue.lastIndexOf('.')) : null;
return new AvailablePlugin(pluginName, canonical, description, latestVersion, author, icon, changelog, readme, license, minServerVersion, priorToServerVersion, minJavaVersion, downloadUrl, fileSize, releaseDate);
}
Aggregations