Class BundleInstaller


  • public class BundleInstaller
    extends java.lang.Object
    The bundle installer is responsible for discovering, installing, and uninstalling plug-in bundles, as well as linking them to the application at runtime. Plug-in bundles are JAR-like archives that contain the code and resources required by a plug-in. The following kinds of bundles are recognized; each type is identified by a different file extension:
    Bundle types
    Type Extension Description
    Library .selibraryResources and code used by other plug-ins
    Theme .setheme A user interface theme (compiled code only)
    Extension.seext Extension plug-ins that are loaded during startup
    Plug-in .seplugin Regular (activated or injected) plug-ins

    Note: Some plug-in files may have an additional extension, .pbz. These are plug-in bundles that have been published to prepare them for inclusion in the plug-in catalog. They cannot be installed as-is, but must first be unpacked into the standard format. See PluginBundlePublisher.

    Plug-in loading happens primarily in three stages: discovery, linking, and instantiation. During discovery, the plug-in folder is scanned for plug-in bundle files of a particular type. After checking each bundle for validity, and converting the bundle to FORMAT_PLAIN if required (see PluginBundle), the bundle's PluginRoot is obtained and the bundle is linked to the application. For library bundles, information about the bundle is obtained from the root file and an InstalledLibrary is created. For other bundles, information is obtained both from the root file and from the theme or plug-in that the bundle contains. This is done by instantiating the plug-in in information probe mode (see PluginContext.isInformationProbe()). Using this information, an InstalledPlugin or InstalledTheme is created. (An InstalledPlugin is not the plug-in itself, but it can be used to create an instance of the plug-in.) Extensions are discovered, linked, and instantiated all at once during application startup. Other plug-ins are discovered and linked during start-up, but are started later (see StrangeEons.loadPlugins()).

    Since:
    2.1
    Author:
    Chris Jennings
    • Field Summary

      Fields 
      Modifier and Type Field Description
      static java.lang.String EXTENSION_FILE_EXT
      The file extension used by extension plug-in bundles (.seext)
      static int INSTALL_FLAG_EXTENSION
      An installation flag that indicates that an extension plug-in bundle was installed.
      static int INSTALL_FLAG_LIBRARY
      An installation flag that indicates that a library bundle was installed.
      static int INSTALL_FLAG_PLUGIN
      An installation flag that indicates that a regular plug-in bundle was installed.
      static int INSTALL_FLAG_REGRESSED
      An installation flag that indicates that a plug-in bundle was "updated" to a previous version of the plug-in.
      static int INSTALL_FLAG_RESTART_REQUIRED
      An installation flag that indicates that a restart is required.
      static int INSTALL_FLAG_THEME
      An installation flag that indicates that a theme bundle was installed.
      static int INSTALL_FLAG_UPDATED
      An installation flag that indicates that a plug-in bundle was updated (or will be when the application restarts).
      static java.lang.String LIBRARY_FILE_EXT
      The file extension used by library bundles (.selibrary)
      static java.lang.String PLUGIN_FILE_EXT
      The file extension used by plug-in bundles (.seplugin)
      static java.io.File PLUGIN_FOLDER
      The folder where plug-ins are installed.
      static java.lang.String THEME_FILE_EXT
      The file extension used by theme plug-in bundles (.setheme)
      static java.lang.String UPDATE_FILE_EXT
      The file extension used to by a bundle that will update an existing bundle at next application start (.autoupdate)
      static java.lang.String USER_PLUGIN_FOLDER_KEY
      A user settings key that points to an additional folder to search for plug-ins.
    • Field Detail

      • PLUGIN_FOLDER

        public static final java.io.File PLUGIN_FOLDER
        The folder where plug-ins are installed.
      • USER_PLUGIN_FOLDER_KEY

        public static final java.lang.String USER_PLUGIN_FOLDER_KEY
        A user settings key that points to an additional folder to search for plug-ins.
        See Also:
        Constant Field Values
      • EXTENSION_FILE_EXT

        public static final java.lang.String EXTENSION_FILE_EXT
        The file extension used by extension plug-in bundles (.seext)
        See Also:
        Constant Field Values
      • PLUGIN_FILE_EXT

        public static final java.lang.String PLUGIN_FILE_EXT
        The file extension used by plug-in bundles (.seplugin)
        See Also:
        Constant Field Values
      • THEME_FILE_EXT

        public static final java.lang.String THEME_FILE_EXT
        The file extension used by theme plug-in bundles (.setheme)
        See Also:
        Constant Field Values
      • LIBRARY_FILE_EXT

        public static final java.lang.String LIBRARY_FILE_EXT
        The file extension used by library bundles (.selibrary)
        See Also:
        Constant Field Values
      • UPDATE_FILE_EXT

        public static final java.lang.String UPDATE_FILE_EXT
        The file extension used to by a bundle that will update an existing bundle at next application start (.autoupdate)
        See Also:
        Constant Field Values
      • INSTALL_FLAG_RESTART_REQUIRED

        public static final int INSTALL_FLAG_RESTART_REQUIRED
        An installation flag that indicates that a restart is required.
        See Also:
        Constant Field Values
      • INSTALL_FLAG_LIBRARY

        public static final int INSTALL_FLAG_LIBRARY
        An installation flag that indicates that a library bundle was installed.
        See Also:
        Constant Field Values
      • INSTALL_FLAG_THEME

        public static final int INSTALL_FLAG_THEME
        An installation flag that indicates that a theme bundle was installed.
        See Also:
        Constant Field Values
      • INSTALL_FLAG_EXTENSION

        public static final int INSTALL_FLAG_EXTENSION
        An installation flag that indicates that an extension plug-in bundle was installed.
        See Also:
        Constant Field Values
      • INSTALL_FLAG_PLUGIN

        public static final int INSTALL_FLAG_PLUGIN
        An installation flag that indicates that a regular plug-in bundle was installed.
        See Also:
        Constant Field Values
      • INSTALL_FLAG_UPDATED

        public static final int INSTALL_FLAG_UPDATED
        An installation flag that indicates that a plug-in bundle was updated (or will be when the application restarts).
        See Also:
        Constant Field Values
      • INSTALL_FLAG_REGRESSED

        public static final int INSTALL_FLAG_REGRESSED
        An installation flag that indicates that a plug-in bundle was "updated" to a previous version of the plug-in. (The updated flag bit will also be set.)
        See Also:
        Constant Field Values
    • Method Detail

      • setTestBundles

        public static void setTestBundles​(java.io.File[] bundles)
        Sets one or more special bundles to be loaded as if they were in a plug-in folder. This is normally set by starting the application with the --plugintest option.
        Parameters:
        bundles - the non-null files containing the bundle to test
      • getTestBundles

        public static java.io.File[] getTestBundles()
        Returns a new array containing all of the registered test bundles, or an empty array if there are no test bundles.
        Returns:
        files containing bundles to test
      • hasTestBundles

        public static boolean hasTestBundles()
        Returns true if and only if the app is running in plug-in test mode.
      • getApplicationLibrary

        public static java.io.File getApplicationLibrary()
        Returns a file representing the location of the main application's .selibrary file or base class directory. The location can be decoded if the application is unpacked to the local file system or if it is stored in a plain plug-in bundle. If not, then an AssertionError will be thrown.
        Returns:
        the main application archive, or the root folder for the class path
      • applyPendingBundleUpdates

        public static void applyPendingBundleUpdates()
        Applies pending bundle updates by copying .autoupdate bundles over their old versions. This is called once during application start, before any bundles are installed.
      • getInstalledPlugins

        public static InstalledPlugin[] getInstalledPlugins()
        Returns an array of the installed plug-ins (from .seplugin bundles and system plug-ins).
        Returns:
        a copy of the installed (not necessarily running) Plugin.ACTIVATED and Plugin.INJECTED plug-ins
      • loadLibraryBundles

        public static void loadLibraryBundles()
        Searches for library bundles (.selibrary files) in the plug-in folders, and attempts to link the application to any libraries that it finds. This method is not normally called by user code. To install a library bundle, call installPluginBundle(java.io.File).
        See Also:
        getInstalledLibraries()
      • getInstalledLibraries

        public static InstalledLibrary[] getInstalledLibraries()
        Returns an array of the available InstalledLibrary objects representing libraries loaded by the plug-in system.
        Returns:
        an array of discovered libraries, sorted by name
      • loadThemeBundles

        public static void loadThemeBundles()
        Searches for theme bundles (.setheme files) in the plug-in folders, installing any themes that it finds.
        See Also:
        getInstalledThemes()
      • getInstalledThemeForClassName

        public static InstalledTheme getInstalledThemeForClassName​(java.lang.String className)
        Returns the InstalledTheme whose Theme class has the name className, or null if no such theme is available.
        Parameters:
        className - the class name of the theme to search for
        Returns:
        the InstalledTheme with the class name, or null
      • loadExtensionBundles

        public static void loadExtensionBundles​(ProgressListener pl)
        Searches for extension bundles (.seext files) in the plug-in folders and attempts to start extension plug-ins that it finds. This is called during application startup. It should never be called by user code.
        Parameters:
        pl - if non-null, this listener will be called periodically with updates on installation progress
        See Also:
        unloadExtensions(), getInstalledExtensions()
      • getFailedUUIDs

        public static java.util.Set<java.util.UUID> getFailedUUIDs()
        Returns an immutable set containing the UUIDs of bundles that failed to start.
        Returns:
        a (possibly empty) set of UUIDs for plug-ins that failed to start
      • unloadExtensions

        public static void unloadExtensions()
        Shuts down installed extensions. This method is called during application shutdown. It should never be called by user code.
      • getInstalledBundleObjectsForUUID

        public static InstalledBundleObject[] getInstalledBundleObjectsForUUID​(java.util.UUID uuid)
        Returns the installed libraries, themes, plug-ins, etc. with the given UUID (possibly empty). Typically, there is at most one installed bundle object with a given UUID, but technically a plug-in bundle can contain multiple plug-ins.
        Parameters:
        uuid - the UUID to search for
        Returns:
        an array of the installed objects that were loaded from the bundle with the specified URL (possibly empty)
        See Also:
        CatalogID.getUUID()
      • disablePluginLoading

        public static void disablePluginLoading()
        Calling this method will prevent plug-ins bundles from being loaded, except for any test bundles specified on the command line.
      • getInstalledCatalogID

        public static CatalogID getInstalledCatalogID​(java.util.UUID uuid)
        Returns the CatalogID extracted from a discovered bundle whose UUID matches uuid, or null.
        Parameters:
        uuid - the UUID to match against installed catalog IDs
        Returns:
        the ID associated with the UUID, or null
      • isUncatalogedBundleName

        public static boolean isUncatalogedBundleName​(java.lang.String name)
        Returns true if a bundle with this file name but no catalog information has been installed. It will be assumed by the catalog system then when a catalog is opened that contains a bundle whose name is the same as a bundle with no ID, the new bundle (now with catalog info) updates the old bundle.
        Parameters:
        name - the name to check against installed bundles
        Returns:
        true if a bundle with this name and no catalog information is installed
      • getInstalledCatalogIDs

        public static CatalogID[] getInstalledCatalogIDs()
        Returns all of the CatalogIDs from discovered bundles that include catalog information.
        Returns:
        installed catalog IDs
      • getUncataloguedBundleNames

        public static java.lang.String[] getUncataloguedBundleNames()
        Returns the names (without path information) of all installed bundles that do not include catalog information.
        Returns:
        uncatalogued bundle file names
      • getBundleFileForPlugin

        public static java.io.File getBundleFileForPlugin​(java.lang.String identifier)
        Returns the file that a plug-in is stored in, or null if the plug-in is not stored in a bundle.
        Parameters:
        identifier - the normalized plug-in identifier, such as a class name
        Returns:
        the bundle file for the plug-in
        See Also:
        getPluginBundle(java.io.File)
      • getBundleFileForUUID

        public static java.io.File getBundleFileForUUID​(java.util.UUID uuid)
        Returns the plug-in bundle file whose catalog ID uses the specified UUID.
        Parameters:
        uuid - the unique ID of the bundle's catalog ID
        Returns:
        the file that contains this UUID, or null
        See Also:
        getPluginBundle(java.io.File)
      • getPluginBundle

        public static PluginBundle getPluginBundle​(java.io.File f)
        Returns the PluginBundle associated with a loaded plug-in bundle, or null if the file is not a loaded bundle.
        Parameters:
        f - the bundle file to match
        Returns:
        the bundle file's plug-in bundle, or null
      • getPluginBundle

        public static PluginBundle getPluginBundle​(java.util.UUID uuid)
        Returns the PluginBundle associated with the loaded plug-in that has the specified UUID, or null if there is no such loaded bundle.
        Parameters:
        uuid - the UUID of the target bundle, as specified in its catalog ID
        Returns:
        the loaded bundle with the target UUID, or null
      • isPluginBundleInstalled

        public static boolean isPluginBundleInstalled​(java.util.UUID uuid)
        Checks if a plug-in with the given UUID is installed.
        Parameters:
        uuid - the UUID of the plug-in
        Returns:
        whether the plug-in is installed or not
      • isPluginBundleInstalled

        public static boolean isPluginBundleInstalled​(CatalogID catId)
        Checks if a plug-in with the given CatalogID, or a newer version, is installed.
        Parameters:
        catId - the CatalogID of the plug-in
        Returns:
        whether the plug-in, or a newer version, is installed or not
      • isPluginBundleInstalled

        public static boolean isPluginBundleInstalled​(java.lang.String rawId)
        Checks if a plug-in with the given identifier is installed. The identifier should be a string which either contains a UUID or the string representation of a CatalogID. If it is a CatalogID, then the version of the installed plug-in must match or be newer.
        Parameters:
        rawId - the identifier of the plug-in
        Returns:
        whether the plug-in, or a newer version, is installed or not
        Throws:
        java.lang.IllegalArgumentException - if the identifier is invalid
      • getDiscoveredBundleFiles

        public static java.io.File[] getDiscoveredBundleFiles()
        Returns an array of the bundle files that have been dynamically added to the class path. This set may include bundles that were discovered, but not loaded (for example, if the bundle file was corrupt). In these cases, calling getPluginBundle for the unloadable bundle will return null.
        Returns:
        an array of discovered bundle files
        See Also:
        getPluginBundle(java.io.File)
      • getPluginClassLoader

        public static java.lang.ClassLoader getPluginClassLoader()
        Returns the class loader for the plug-in system.
        Returns:
        the default parent class loader for the plug-in system
      • showBundleInstallationNotes

        public static void showBundleInstallationNotes​(java.io.File bundleFile)
        If the plug-in bundle specified by bundleFile contains installation notes, these are shown in a pop-up window.
        Parameters:
        bundleFile - the plain bundle that may contain installation notes
      • listPluginsInBundle

        public static java.lang.String[] listPluginsInBundle​(java.io.File bundle)
        Returns a list of the plug-in identifiers in a bundle. A plug-in identifier is either a class name (for a compiled plug-in class) or a script identifier that consists of the string script: followed by a URL that points to the script.
        Parameters:
        bundle - the bundle file to list plug-ins from
        Returns:
        an array, possibly empty, of plug-ins in the script
      • installPluginBundle

        public static int installPluginBundle​(java.io.File bundleFile)
                                       throws java.io.IOException
        Installs a plug-in file by copying it to the user's plug-in folder. If the source bundle is in a published form (the format typically used for network transport by the catalogue system), it must be unpacked prior to installation with this method. If the bundle is a regular bundle file in Web-safe format, it will be converted to plain format by this method. If the bundle's catalogue ID is the same as an already installed bundle, then this bundle will be copied to the folder as an .autoupdate file and the installation will complete the next time the application starts.

        If the bundle file is in the plug-in folder and has already been discovered and loaded by the plug-in system, then if it is currently marked for uninstallation, the uninstall request will be cleared.

        If the bundle is installed successfully, its installer (if any) will then be run. If it is copied to an .autoupdate file, the installer will run when the plug-in is installed after restart. this method will clear the uninstall request.

        This method returns a bitmask of flags that indicate the type of bundle that was installed, the installation type, and whether a restart is required. If the installer takes no action or simply clears the uninstallation flag, it returns 0. If several bundles are being installed together, successive return values can be binary or'd together to obtain a summary of all actions that were taken.

        This method does not re-scan the plug-in folders to link or start the newly installed bundle. If a plug-in (as opposed to a theme or extension) was installed, and if it was not an update, then the new plug-in can be installed by loading the bundle, then reloading all plug-ins.

        Parameters:
        bundleFile - the file to install
        Returns:
        a bitmask summarizing the result, or 0
        Throws:
        java.lang.NullPointerException - if the bundle file is null
        java.io.IOException - if an I/O error occurs while installing the bundle
        See Also:
        INSTALL_FLAG_RESTART_REQUIRED, INSTALL_FLAG_UPDATED, INSTALL_FLAG_REGRESSED, INSTALL_FLAG_LIBRARY, INSTALL_FLAG_THEME, INSTALL_FLAG_EXTENSION, INSTALL_FLAG_PLUGIN
      • finishBundleInstallation

        public static void finishBundleInstallation​(int flags)
        Completes the installation of one or more bundles by rescanning the plug-in folders and loading new plug-ins. If a restart is required to complete installation, StrangeEonsAppWindow.suggestRestart(java.lang.String) will be called to inform the user.
        Parameters:
        flags - the binary-or of all installation flags returned by the plug-ins that were installed
      • uninstallPluginBundle

        public static void uninstallPluginBundle​(PluginBundle bundle)
        Marks a plug-in for uninstallation. The bundle will not be uninstalled immediately. If the bundle is still marked for uninstallation at application shutdown, then the bundle's uninstaller will run (if any). When the application is next started, the bundle file will be deleted.
        Parameters:
        bundle - the bundle to uninstall
      • isFXRuntimeAvailable

        @Deprecated
        public static boolean isFXRuntimeAvailable()
        Deprecated.
        This method returns false.
        Returns true if the JavaFX runtime is available. This method will attempt to locate, dynamically load, and start the runtime before returning false.
        Returns:
        true if the JavaFX runtime is available