From 6b76d4fb30104f08a7c6b33d7cf05fb71179f6de Mon Sep 17 00:00:00 2001 From: James Moger <james.moger@gitblit.com> Date: Thu, 04 Sep 2014 14:20:28 -0400 Subject: [PATCH] Merge branch 'ticket/151' into develop --- src/main/java/com/gitblit/manager/PluginManager.java | 91 +++++++++++++++++++++++++++++++++++++-------- 1 files changed, 74 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/gitblit/manager/PluginManager.java b/src/main/java/com/gitblit/manager/PluginManager.java index 405dc51..874e24b 100644 --- a/src/main/java/com/gitblit/manager/PluginManager.java +++ b/src/main/java/com/gitblit/manager/PluginManager.java @@ -37,7 +37,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import ro.fortsoft.pf4j.DefaultExtensionFinder; import ro.fortsoft.pf4j.DefaultPluginManager; +import ro.fortsoft.pf4j.ExtensionFinder; import ro.fortsoft.pf4j.PluginClassLoader; import ro.fortsoft.pf4j.PluginState; import ro.fortsoft.pf4j.PluginStateEvent; @@ -47,6 +49,7 @@ import com.gitblit.Constants; import com.gitblit.Keys; +import com.gitblit.extensions.GitblitPlugin; import com.gitblit.models.PluginRegistry; import com.gitblit.models.PluginRegistry.InstallState; import com.gitblit.models.PluginRegistry.PluginRegistration; @@ -57,6 +60,8 @@ import com.gitblit.utils.StringUtils; import com.google.common.io.Files; import com.google.common.io.InputSupplier; +import com.google.inject.Inject; +import com.google.inject.Singleton; /** * The plugin manager maintains the lifecycle of plugins. It is exposed as @@ -67,32 +72,23 @@ * @author James Moger * */ +@Singleton public class PluginManager implements IPluginManager, PluginStateListener { private final Logger logger = LoggerFactory.getLogger(getClass()); - private final DefaultPluginManager pf4j; - private final IRuntimeManager runtimeManager; + + private DefaultPluginManager pf4j; // timeout defaults of Maven 3.0.4 in seconds private int connectTimeout = 20; private int readTimeout = 12800; + @Inject public PluginManager(IRuntimeManager runtimeManager) { - File dir = runtimeManager.getFileOrFolder(Keys.plugins.folder, "${baseFolder}/plugins"); - dir.mkdirs(); this.runtimeManager = runtimeManager; - - this.pf4j = new DefaultPluginManager(dir); - - try { - Version systemVersion = Version.createVersion(Constants.getVersion()); - pf4j.setSystemVersion(systemVersion); - } catch (Exception e) { - logger.error(null, e); - } } @Override @@ -107,6 +103,42 @@ @Override public PluginManager start() { + File dir = runtimeManager.getFileOrFolder(Keys.plugins.folder, "${baseFolder}/plugins"); + dir.mkdirs(); + pf4j = new DefaultPluginManager(dir) { + @Override + protected ExtensionFinder createExtensionFinder() { + DefaultExtensionFinder extensionFinder = new DefaultExtensionFinder(this) { + @Override + protected ExtensionFactory createExtensionFactory() { + return new ExtensionFactory() { + @Override + public Object create(Class<?> extensionType) { + // instantiate && inject the extension + logger.debug("Create instance for extension '{}'", extensionType.getName()); + try { + return runtimeManager.getInjector().getInstance(extensionType); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + return null; + } + + }; + } + }; + addPluginStateListener(extensionFinder); + + return extensionFinder; + } + }; + + try { + Version systemVersion = Version.createVersion(Constants.getVersion()); + pf4j.setSystemVersion(systemVersion); + } catch (Exception e) { + logger.error(null, e); + } pf4j.loadPlugins(); logger.debug("Starting plugins"); pf4j.startPlugins(); @@ -141,6 +173,12 @@ return false; } + // allow the plugin to prepare for operation after installation + PluginWrapper pluginWrapper = pf4j.getPlugin(pluginId); + if (pluginWrapper.getPlugin() instanceof GitblitPlugin) { + ((GitblitPlugin) pluginWrapper.getPlugin()).onInstall(); + } + PluginState state = pf4j.startPlugin(pluginId); return PluginState.STARTED.equals(state); } @@ -154,11 +192,18 @@ return false; } - if (deletePlugin(pluginId)) { + Version oldVersion = pf4j.getPlugin(pluginId).getDescriptor().getVersion(); + if (removePlugin(pluginId, false)) { String newPluginId = pf4j.loadPlugin(file); if (StringUtils.isEmpty(newPluginId)) { logger.error("Failed to load plugin {}", file); return false; + } + + // the plugin to handle an upgrade + PluginWrapper pluginWrapper = pf4j.getPlugin(newPluginId); + if (pluginWrapper.getPlugin() instanceof GitblitPlugin) { + ((GitblitPlugin) pluginWrapper.getPlugin()).onUpgrade(oldVersion); } PluginState state = pf4j.startPlugin(newPluginId); @@ -183,9 +228,21 @@ } @Override - public synchronized boolean deletePlugin(String pluginId) { + public synchronized boolean uninstallPlugin(String pluginId) { + return removePlugin(pluginId, true); + } + + protected boolean removePlugin(String pluginId, boolean isUninstall) { PluginWrapper pluginWrapper = getPlugin(pluginId); final String name = pluginWrapper.getPluginPath().substring(1); + + if (isUninstall) { + // allow the plugin to prepare for uninstallation + if (pluginWrapper.getPlugin() instanceof GitblitPlugin) { + ((GitblitPlugin) pluginWrapper.getPlugin()).onUninstall(); + } + } + if (pf4j.deletePlugin(pluginId)) { // delete the checksums @@ -351,7 +408,7 @@ List<PluginRegistration> list = getRegisteredPlugins(); Iterator<PluginRegistration> itr = list.iterator(); while (itr.hasNext()) { - if (state != itr.next().getInstallState()) { + if (state != itr.next().getInstallState(getSystemVersion())) { itr.remove(); } } @@ -377,7 +434,7 @@ PluginRelease pv; if (StringUtils.isEmpty(version)) { - pv = reg.getCurrentRelease(); + pv = reg.getCurrentRelease(getSystemVersion()); } else { pv = reg.getRelease(version); } -- Gitblit v1.9.1