Search in sources :

Example 1 with Version

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;
}
Also used : Version(org.jivesoftware.util.Version) SAXReader(org.dom4j.io.SAXReader) ZipEntry(java.util.zip.ZipEntry) Element(org.dom4j.Element) JarFile(java.util.jar.JarFile) Document(org.dom4j.Document) JarFile(java.util.jar.JarFile)

Example 2 with Version

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;
    }
}
Also used : Attribute(org.dom4j.Attribute) SAXReader(org.dom4j.io.SAXReader) Element(org.dom4j.Element) Document(org.dom4j.Document) Version(org.jivesoftware.util.Version)

Example 3 with Version

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);
}
Also used : MalformedURLException(java.net.MalformedURLException) Version(org.jivesoftware.util.Version) JavaSpecVersion(org.jivesoftware.util.JavaSpecVersion) ParseException(java.text.ParseException) URL(java.net.URL) JavaSpecVersion(org.jivesoftware.util.JavaSpecVersion)

Aggregations

Version (org.jivesoftware.util.Version)3 Document (org.dom4j.Document)2 Element (org.dom4j.Element)2 SAXReader (org.dom4j.io.SAXReader)2 MalformedURLException (java.net.MalformedURLException)1 URL (java.net.URL)1 ParseException (java.text.ParseException)1 JarFile (java.util.jar.JarFile)1 ZipEntry (java.util.zip.ZipEntry)1 Attribute (org.dom4j.Attribute)1 JavaSpecVersion (org.jivesoftware.util.JavaSpecVersion)1