Class BundleInstaller
- java.lang.Object
-
- ca.cgjennings.apps.arkham.plugins.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 .selibrary Resources 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 (seePluginBundle
), the bundle'sPluginRoot
is obtained and the bundle is linked to the application. For library bundles, information about the bundle is obtained from the root file and anInstalledLibrary
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 (seePluginContext.isInformationProbe()
). Using this information, anInstalledPlugin
orInstalledTheme
is created. (AnInstalledPlugin
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 (seeStrangeEons.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.
-
Method Summary
All Methods Static Methods Concrete Methods Deprecated Methods Modifier and Type Method Description static void
applyPendingBundleUpdates()
Applies pending bundle updates by copying .autoupdate bundles over their old versions.static void
disablePluginLoading()
Calling this method will prevent plug-ins bundles from being loaded, except for any test bundles specified on the command line.static void
finishBundleInstallation(int flags)
Completes the installation of one or more bundles by rescanning the plug-in folders and loading new plug-ins.static java.io.File
getApplicationLibrary()
Returns a file representing the location of the main application's .selibrary file or base class directory.static java.io.File
getBundleFileForPlugin(java.lang.String identifier)
Returns the file that a plug-in is stored in, ornull
if the plug-in is not stored in a bundle.static java.io.File
getBundleFileForUUID(java.util.UUID uuid)
Returns the plug-in bundle file whose catalog ID uses the specified UUID.static java.io.File[]
getDiscoveredBundleFiles()
Returns an array of the bundle files that have been dynamically added to the class path.static java.util.Set<java.util.UUID>
getFailedUUIDs()
Returns an immutable set containing the UUIDs of bundles that failed to start.static InstalledBundleObject[]
getInstalledBundleObjectsForUUID(java.util.UUID uuid)
Returns the installed libraries, themes, plug-ins, etc.static CatalogID
getInstalledCatalogID(java.util.UUID uuid)
static CatalogID[]
getInstalledCatalogIDs()
Returns all of theCatalogID
s from discovered bundles that include catalog information.static InstalledExtension[]
getInstalledExtensions()
Returns an array of the extension plug-ins that were loaded byloadExtensionBundles(ca.cgjennings.algo.ProgressListener)
.static InstalledLibrary[]
getInstalledLibraries()
Returns an array of the availableInstalledLibrary
objects representing libraries loaded by the plug-in system.static InstalledPlugin[]
getInstalledPlugins()
Returns an array of the installed plug-ins (from .seplugin bundles and system plug-ins).static InstalledTheme
getInstalledThemeForClassName(java.lang.String className)
Returns theInstalledTheme
whoseTheme
class has the name className, ornull
if no such theme is available.static InstalledTheme[]
getInstalledThemes()
Returns an array of the availableInstalledTheme
s.static PluginBundle
getPluginBundle(java.io.File f)
Returns thePluginBundle
associated with a loaded plug-in bundle, ornull
if the file is not a loaded bundle.static PluginBundle
getPluginBundle(java.util.UUID uuid)
Returns thePluginBundle
associated with the loaded plug-in that has the specified UUID, ornull
if there is no such loaded bundle.static java.lang.ClassLoader
getPluginClassLoader()
Returns the class loader for the plug-in system.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.static java.lang.String[]
getUncataloguedBundleNames()
Returns the names (without path information) of all installed bundles that do not include catalog information.static boolean
hasTestBundles()
Returns true if and only if the app is running in plug-in test mode.static int
installPluginBundle(java.io.File bundleFile)
Installs a plug-in file by copying it to the user's plug-in folder.static boolean
isFXRuntimeAvailable()
Deprecated.This method returnsfalse
.static boolean
isPluginBundleInstalled(CatalogID catId)
Checks if a plug-in with the givenCatalogID
, or a newer version, is installed.static boolean
isPluginBundleInstalled(java.lang.String rawId)
Checks if a plug-in with the given identifier is installed.static boolean
isPluginBundleInstalled(java.util.UUID uuid)
Checks if a plug-in with the given UUID is installed.static boolean
isUncatalogedBundleName(java.lang.String name)
Returnstrue
if a bundle with this file name but no catalog information has been installed.static java.lang.String[]
listPluginsInBundle(java.io.File bundle)
Returns a list of the plug-in identifiers in a bundle.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.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.static void
loadPluginBundles()
Searches for plug-in bundles (.seplugin
files) in the plug-in folders.static void
loadThemeBundles()
Searches for theme bundles (.setheme
files) in the plug-in folders, installing any themes that it finds.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.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.static void
uninstallPluginBundle(PluginBundle bundle)
Marks a plug-in for uninstallation.static void
unloadExtensions()
Shuts down installed extensions.
-
-
-
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 anAssertionError
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.
-
loadPluginBundles
public static void loadPluginBundles()
Searches for plug-in bundles (.seplugin
files) in the plug-in folders. Newly discovered plug-ins are linked to the application and added to a list of installed plug-ins, but they are not started immediately. This is because regular plug-ins can be reloaded while the application is running, a process which is coordinated by the application.
-
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
andPlugin.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, callinstallPluginBundle(java.io.File)
.- See Also:
getInstalledLibraries()
-
getInstalledLibraries
public static InstalledLibrary[] getInstalledLibraries()
Returns an array of the availableInstalledLibrary
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()
-
getInstalledThemes
public static InstalledTheme[] getInstalledThemes()
Returns an array of the availableInstalledTheme
s.- Returns:
- an array of discovered themes, sorted by theme name
-
getInstalledThemeForClassName
public static InstalledTheme getInstalledThemeForClassName(java.lang.String className)
Returns theInstalledTheme
whoseTheme
class has the name className, ornull
if no such theme is available.- Parameters:
className
- the class name of the theme to search for- Returns:
- the
InstalledTheme
with the class name, ornull
-
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
-
getInstalledExtensions
public static InstalledExtension[] getInstalledExtensions()
Returns an array of the extension plug-ins that were loaded byloadExtensionBundles(ca.cgjennings.algo.ProgressListener)
. This should only be used for informational purposes, e.g., querying for name, description, and version.- Returns:
- an array of the installed extension plug-ins
-
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)
- 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)
Returnstrue
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 theCatalogID
s 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, ornull
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 thePluginBundle
associated with a loaded plug-in bundle, ornull
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 thePluginBundle
associated with the loaded plug-in that has the specified UUID, ornull
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 givenCatalogID
, or a newer version, is installed.- Parameters:
catId
- theCatalogID
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 aCatalogID
. If it is aCatalogID
, 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, callinggetPluginBundle
for the unloadable bundle will returnnull
.- 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 isnull
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 returnsfalse
.Returnstrue
if the JavaFX runtime is available. This method will attempt to locate, dynamically load, and start the runtime before returningfalse
.- Returns:
true
if the JavaFX runtime is available
-
-