From cf4004e8d64399f6fc722fcb313eaaae6a65fa20 Mon Sep 17 00:00:00 2001
From: James Moger <james.moger@gitblit.com>
Date: Thu, 17 Apr 2014 18:08:12 -0400
Subject: [PATCH] Add plugin (un)install lifecycle methods

---
 src/site/plugins_extensions.mkd                                        |   17 ++++++++
 src/main/java/com/gitblit/extensions/GitblitPlugin.java                |   34 +++++++++++++++++
 src/main/java/com/gitblit/manager/IPluginManager.java                  |    2 
 src/main/java/com/gitblit/manager/PluginManager.java                   |   30 ++++++++++++++-
 src/main/java/com/gitblit/manager/GitblitManager.java                  |    4 +-
 src/main/java/com/gitblit/transport/ssh/commands/PluginDispatcher.java |    2 
 6 files changed, 83 insertions(+), 6 deletions(-)

diff --git a/src/main/java/com/gitblit/extensions/GitblitPlugin.java b/src/main/java/com/gitblit/extensions/GitblitPlugin.java
index 129f584..d0603eb 100644
--- a/src/main/java/com/gitblit/extensions/GitblitPlugin.java
+++ b/src/main/java/com/gitblit/extensions/GitblitPlugin.java
@@ -17,11 +17,45 @@
 
 import ro.fortsoft.pf4j.Plugin;
 import ro.fortsoft.pf4j.PluginWrapper;
+import ro.fortsoft.pf4j.Version;
 
+/**
+ * Parent class of Gitblit plugins.
+ *
+ * @author James Moger
+ * @since 1.5.0
+ */
 public abstract class GitblitPlugin extends Plugin {
 
 	public GitblitPlugin(PluginWrapper wrapper) {
 		super(wrapper);
 	}
 
+	/**
+	 * Called after a plugin as been loaded but before it is started for the
+	 * first time.  This allows the plugin to install settings or perform any
+	 * other required first-time initialization.
+	 *
+	 * @since 1.5.0
+	 */
+	public abstract void onInstall();
+
+	/**
+	 * Called after an updated plugin has been installed but before the updated
+	 * plugin is started.  The oldVersion is passed as a parameter in the event
+	 * that special processing needs to be executed.
+	 *
+	 * @param oldVersion
+	 * @since 1.5.0
+	 */
+	public abstract void onUpgrade(Version oldVersion);
+
+	/**
+	 * Called before a plugin has been unloaded and deleted from the system.
+	 * This allows a plugin to remove any settings it may have created or
+	 * perform and other necessary cleanup.
+	 *
+	 * @since 1.5.0
+	 */
+	public abstract void onUninstall();
 }
diff --git a/src/main/java/com/gitblit/manager/GitblitManager.java b/src/main/java/com/gitblit/manager/GitblitManager.java
index 4ecb9c6..61a0949 100644
--- a/src/main/java/com/gitblit/manager/GitblitManager.java
+++ b/src/main/java/com/gitblit/manager/GitblitManager.java
@@ -1251,8 +1251,8 @@
 	}
 
 	@Override
-	public boolean deletePlugin(String pluginId) {
-		return pluginManager.deletePlugin(pluginId);
+	public boolean uninstallPlugin(String pluginId) {
+		return pluginManager.uninstallPlugin(pluginId);
 	}
 
 	@Override
diff --git a/src/main/java/com/gitblit/manager/IPluginManager.java b/src/main/java/com/gitblit/manager/IPluginManager.java
index bf04619..528bbed 100644
--- a/src/main/java/com/gitblit/manager/IPluginManager.java
+++ b/src/main/java/com/gitblit/manager/IPluginManager.java
@@ -122,7 +122,7 @@
      * @param pluginId
      * @return true if successful
      */
-    boolean deletePlugin(String pluginId);
+    boolean uninstallPlugin(String pluginId);
 
     /**
      * Refresh the plugin registry.
diff --git a/src/main/java/com/gitblit/manager/PluginManager.java b/src/main/java/com/gitblit/manager/PluginManager.java
index 405dc51..40d302d 100644
--- a/src/main/java/com/gitblit/manager/PluginManager.java
+++ b/src/main/java/com/gitblit/manager/PluginManager.java
@@ -47,6 +47,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;
@@ -141,6 +142,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 +161,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 +197,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
diff --git a/src/main/java/com/gitblit/transport/ssh/commands/PluginDispatcher.java b/src/main/java/com/gitblit/transport/ssh/commands/PluginDispatcher.java
index 37649ea..62b1357 100644
--- a/src/main/java/com/gitblit/transport/ssh/commands/PluginDispatcher.java
+++ b/src/main/java/com/gitblit/transport/ssh/commands/PluginDispatcher.java
@@ -614,7 +614,7 @@
 				throw new UnloggedFailure(String.format("Plugin %s is not installed!", id));
 			}
 
-			if (gitblit.deletePlugin(pluginWrapper.getPluginId())) {
+			if (gitblit.uninstallPlugin(pluginWrapper.getPluginId())) {
 				stdout.println(String.format("Uninstalled %s", pluginWrapper.getPluginId()));
 			} else {
 				throw new UnloggedFailure(1, String.format("Failed to uninstall %s", pluginWrapper.getPluginId()));
diff --git a/src/site/plugins_extensions.mkd b/src/site/plugins_extensions.mkd
index 6e0e52e..86d0729 100644
--- a/src/site/plugins_extensions.mkd
+++ b/src/site/plugins_extensions.mkd
@@ -19,6 +19,7 @@
 import com.gitblit.manager.IFederationManager;
 import com.gitblit.manager.IPluginManager;
 import com.gitblit.manager.IGitblit;
+import ro.fortsoft.pf4j.Version;
 
 public class ExamplePlugin extends GitblitPlugin {
 
@@ -34,6 +35,22 @@
         IPluginManager plugins = GitblitContext.getManager(IPluginManager.class);
         IGitblit gitblit = GitblitContext.getManager(IGitblit.class);
     }
+
+    @Override
+    public void stop() {
+    }
+
+    @Override
+    public void onInstall() {
+    }
+
+    @Override
+    public void onUpgrade(Version oldVersion) {
+    }
+
+    @Override
+    public void onUninstall() {
+    }
 }
 ```
 

--
Gitblit v1.9.1