From ba567069542e1f6769097ff78cd9612a9f08eb83 Mon Sep 17 00:00:00 2001
From: James Moger <james.moger@gitblit.com>
Date: Sat, 12 Apr 2014 11:40:10 -0400
Subject: [PATCH] Add TicketHook extension

---
 src/site/setup_plugins.mkd                                   |   23 +++++++
 src/main/java/com/gitblit/ReindexTickets.java                |    6 +-
 src/main/java/com/gitblit/tickets/FileTicketService.java     |    3 +
 src/test/java/com/gitblit/tests/RedisTicketServiceTest.java  |    4 +
 src/main/java/com/gitblit/tickets/ITicketService.java        |   28 +++++++++
 src/test/java/com/gitblit/tests/FileTicketServiceTest.java   |    4 +
 src/main/java/com/gitblit/tickets/BranchTicketService.java   |    3 +
 src/main/java/com/gitblit/GitBlit.java                       |    9 +++
 src/main/java/com/gitblit/tickets/RedisTicketService.java    |    3 +
 src/main/java/com/gitblit/extensions/TicketHook.java         |   46 +++++++++++++++
 src/main/java/com/gitblit/tickets/NullTicketService.java     |    3 +
 src/test/java/com/gitblit/tests/BranchTicketServiceTest.java |    4 +
 12 files changed, 133 insertions(+), 3 deletions(-)

diff --git a/src/main/java/com/gitblit/GitBlit.java b/src/main/java/com/gitblit/GitBlit.java
index 0834252..3db5f08 100644
--- a/src/main/java/com/gitblit/GitBlit.java
+++ b/src/main/java/com/gitblit/GitBlit.java
@@ -352,6 +352,7 @@
 
 					// core managers
 					IRuntimeManager.class,
+					IPluginManager.class,
 					INotificationManager.class,
 					IUserManager.class,
 					IAuthenticationManager.class,
@@ -377,6 +378,10 @@
 
 		@Provides @Singleton IRuntimeManager provideRuntimeManager() {
 			return runtimeManager;
+		}
+
+		@Provides @Singleton IPluginManager providePluginManager() {
+			return pluginManager;
 		}
 
 		@Provides @Singleton INotificationManager provideNotificationManager() {
@@ -410,6 +415,7 @@
 		@Provides @Singleton NullTicketService provideNullTicketService() {
 			return new NullTicketService(
 					runtimeManager,
+					pluginManager,
 					notificationManager,
 					userManager,
 					repositoryManager);
@@ -418,6 +424,7 @@
 		@Provides @Singleton FileTicketService provideFileTicketService() {
 			return new FileTicketService(
 					runtimeManager,
+					pluginManager,
 					notificationManager,
 					userManager,
 					repositoryManager);
@@ -426,6 +433,7 @@
 		@Provides @Singleton BranchTicketService provideBranchTicketService() {
 			return new BranchTicketService(
 					runtimeManager,
+					pluginManager,
 					notificationManager,
 					userManager,
 					repositoryManager);
@@ -434,6 +442,7 @@
 		@Provides @Singleton RedisTicketService provideRedisTicketService() {
 			return new RedisTicketService(
 					runtimeManager,
+					pluginManager,
 					notificationManager,
 					userManager,
 					repositoryManager);
diff --git a/src/main/java/com/gitblit/ReindexTickets.java b/src/main/java/com/gitblit/ReindexTickets.java
index f3d6d26..51ca165 100644
--- a/src/main/java/com/gitblit/ReindexTickets.java
+++ b/src/main/java/com/gitblit/ReindexTickets.java
@@ -139,13 +139,13 @@
 			Class<?> serviceClass = Class.forName(serviceName);
 			if (RedisTicketService.class.isAssignableFrom(serviceClass)) {
 				// Redis ticket service
-				ticketService = new RedisTicketService(runtimeManager, null, null, repositoryManager).start();
+				ticketService = new RedisTicketService(runtimeManager, null, null, null, repositoryManager).start();
 			} else if (BranchTicketService.class.isAssignableFrom(serviceClass)) {
 				// Branch ticket service
-				ticketService = new BranchTicketService(runtimeManager, null, null, repositoryManager).start();
+				ticketService = new BranchTicketService(runtimeManager, null, null, null, repositoryManager).start();
 			} else if (FileTicketService.class.isAssignableFrom(serviceClass)) {
 				// File ticket service
-				ticketService = new FileTicketService(runtimeManager, null, null, repositoryManager).start();
+				ticketService = new FileTicketService(runtimeManager, null, null, null, repositoryManager).start();
 			} else {
 				System.err.println("Unknown ticket service " + serviceName);
 				System.exit(1);
diff --git a/src/main/java/com/gitblit/extensions/TicketHook.java b/src/main/java/com/gitblit/extensions/TicketHook.java
new file mode 100644
index 0000000..3acbef3
--- /dev/null
+++ b/src/main/java/com/gitblit/extensions/TicketHook.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2014 gitblit.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.gitblit.extensions;
+
+import ro.fortsoft.pf4j.ExtensionPoint;
+
+import com.gitblit.models.TicketModel;
+import com.gitblit.models.TicketModel.Change;
+
+/**
+ * Extension point for plugins to respond to Ticket changes.
+ *
+ * @author James Moger
+ *
+ */
+public abstract class TicketHook implements ExtensionPoint {
+
+	/**
+	 * Called when a new ticket is created.
+	 *
+	 * @param ticket
+	 */
+	public abstract void onNewTicket(TicketModel ticket);
+
+	/**
+	 * Called when an existing ticket is updated.  Tickets can be updated for
+	 * many, many reasons like state changes votes, watches, etc.
+	 *
+	 * @param ticket
+	 * @param change
+	 */
+	public abstract void onUpdateTicket(TicketModel ticket, Change change);
+}
diff --git a/src/main/java/com/gitblit/tickets/BranchTicketService.java b/src/main/java/com/gitblit/tickets/BranchTicketService.java
index 56055a4..3a634e0 100644
--- a/src/main/java/com/gitblit/tickets/BranchTicketService.java
+++ b/src/main/java/com/gitblit/tickets/BranchTicketService.java
@@ -58,6 +58,7 @@
 import com.gitblit.Constants;
 import com.gitblit.git.ReceiveCommandEvent;
 import com.gitblit.manager.INotificationManager;
+import com.gitblit.manager.IPluginManager;
 import com.gitblit.manager.IRepositoryManager;
 import com.gitblit.manager.IRuntimeManager;
 import com.gitblit.manager.IUserManager;
@@ -92,11 +93,13 @@
 
 	public BranchTicketService(
 			IRuntimeManager runtimeManager,
+			IPluginManager pluginManager,
 			INotificationManager notificationManager,
 			IUserManager userManager,
 			IRepositoryManager repositoryManager) {
 
 		super(runtimeManager,
+				pluginManager,
 				notificationManager,
 				userManager,
 				repositoryManager);
diff --git a/src/main/java/com/gitblit/tickets/FileTicketService.java b/src/main/java/com/gitblit/tickets/FileTicketService.java
index 2247a66..4386020 100644
--- a/src/main/java/com/gitblit/tickets/FileTicketService.java
+++ b/src/main/java/com/gitblit/tickets/FileTicketService.java
@@ -29,6 +29,7 @@
 
 import com.gitblit.Constants;
 import com.gitblit.manager.INotificationManager;
+import com.gitblit.manager.IPluginManager;
 import com.gitblit.manager.IRepositoryManager;
 import com.gitblit.manager.IRuntimeManager;
 import com.gitblit.manager.IUserManager;
@@ -58,11 +59,13 @@
 
 	public FileTicketService(
 			IRuntimeManager runtimeManager,
+			IPluginManager pluginManager,
 			INotificationManager notificationManager,
 			IUserManager userManager,
 			IRepositoryManager repositoryManager) {
 
 		super(runtimeManager,
+				pluginManager,
 				notificationManager,
 				userManager,
 				repositoryManager);
diff --git a/src/main/java/com/gitblit/tickets/ITicketService.java b/src/main/java/com/gitblit/tickets/ITicketService.java
index 90f9c6d..9522e42 100644
--- a/src/main/java/com/gitblit/tickets/ITicketService.java
+++ b/src/main/java/com/gitblit/tickets/ITicketService.java
@@ -35,7 +35,9 @@
 
 import com.gitblit.IStoredSettings;
 import com.gitblit.Keys;
+import com.gitblit.extensions.TicketHook;
 import com.gitblit.manager.INotificationManager;
+import com.gitblit.manager.IPluginManager;
 import com.gitblit.manager.IRepositoryManager;
 import com.gitblit.manager.IRuntimeManager;
 import com.gitblit.manager.IUserManager;
@@ -94,6 +96,8 @@
 
 	protected final IRepositoryManager repositoryManager;
 
+	protected final IPluginManager pluginManager;
+
 	protected final TicketIndexer indexer;
 
 	private final Cache<TicketKey, TicketModel> ticketsCache;
@@ -136,6 +140,7 @@
 	 */
 	public ITicketService(
 			IRuntimeManager runtimeManager,
+			IPluginManager pluginManager,
 			INotificationManager notificationManager,
 			IUserManager userManager,
 			IRepositoryManager repositoryManager) {
@@ -143,6 +148,7 @@
 		this.log = LoggerFactory.getLogger(getClass());
 		this.settings = runtimeManager.getSettings();
 		this.runtimeManager = runtimeManager;
+		this.pluginManager = pluginManager;
 		this.notificationManager = notificationManager;
 		this.userManager = userManager;
 		this.repositoryManager = repositoryManager;
@@ -832,6 +838,17 @@
 		if (success) {
 			TicketModel ticket = getTicket(repository, ticketId);
 			indexer.index(ticket);
+
+			// call the ticket hooks
+			if (pluginManager != null) {
+				for (TicketHook hook : pluginManager.getExtensions(TicketHook.class)) {
+					try {
+						hook.onNewTicket(ticket);
+					} catch (Exception e) {
+						log.error("Failed to execute extension", e);
+					}
+				}
+			}
 			return ticket;
 		}
 		return null;
@@ -862,6 +879,17 @@
 			TicketModel ticket = getTicket(repository, ticketId);
 			ticketsCache.put(key, ticket);
 			indexer.index(ticket);
+
+			// call the ticket hooks
+			if (pluginManager != null) {
+				for (TicketHook hook : pluginManager.getExtensions(TicketHook.class)) {
+					try {
+						hook.onUpdateTicket(ticket, change);
+					} catch (Exception e) {
+						log.error("Failed to execute extension", e);
+					}
+				}
+			}
 			return ticket;
 		}
 		return null;
diff --git a/src/main/java/com/gitblit/tickets/NullTicketService.java b/src/main/java/com/gitblit/tickets/NullTicketService.java
index 0ff3317..749d801 100644
--- a/src/main/java/com/gitblit/tickets/NullTicketService.java
+++ b/src/main/java/com/gitblit/tickets/NullTicketService.java
@@ -19,6 +19,7 @@
 import java.util.List;
 
 import com.gitblit.manager.INotificationManager;
+import com.gitblit.manager.IPluginManager;
 import com.gitblit.manager.IRepositoryManager;
 import com.gitblit.manager.IRuntimeManager;
 import com.gitblit.manager.IUserManager;
@@ -37,11 +38,13 @@
 
 	public NullTicketService(
 			IRuntimeManager runtimeManager,
+			IPluginManager pluginManager,
 			INotificationManager notificationManager,
 			IUserManager userManager,
 			IRepositoryManager repositoryManager) {
 
 		super(runtimeManager,
+				pluginManager,
 				notificationManager,
 				userManager,
 				repositoryManager);
diff --git a/src/main/java/com/gitblit/tickets/RedisTicketService.java b/src/main/java/com/gitblit/tickets/RedisTicketService.java
index 58f7243..2c5b181 100644
--- a/src/main/java/com/gitblit/tickets/RedisTicketService.java
+++ b/src/main/java/com/gitblit/tickets/RedisTicketService.java
@@ -32,6 +32,7 @@
 
 import com.gitblit.Keys;
 import com.gitblit.manager.INotificationManager;
+import com.gitblit.manager.IPluginManager;
 import com.gitblit.manager.IRepositoryManager;
 import com.gitblit.manager.IRuntimeManager;
 import com.gitblit.manager.IUserManager;
@@ -61,11 +62,13 @@
 
 	public RedisTicketService(
 			IRuntimeManager runtimeManager,
+			IPluginManager pluginManager,
 			INotificationManager notificationManager,
 			IUserManager userManager,
 			IRepositoryManager repositoryManager) {
 
 		super(runtimeManager,
+				pluginManager,
 				notificationManager,
 				userManager,
 				repositoryManager);
diff --git a/src/site/setup_plugins.mkd b/src/site/setup_plugins.mkd
index 4c32e97..6e4e92a 100644
--- a/src/site/setup_plugins.mkd
+++ b/src/site/setup_plugins.mkd
@@ -111,6 +111,29 @@
 }
 ```
 
+### Extension Point: Ticket Hook
+
+You can provide your own custom ticket hook by extending the *TicketHook* class.
+
+```java
+import com.gitblit.extensions.TicketHook;
+import com.gitblit.models.TicketModel;
+import com.gitblit.models.TicketModel.Change;
+import ro.fortsoft.pf4j.Extension;
+
+@Extension
+public class MyTicketHook extends TicketHook {
+
+    @Override
+    public void onNewTicket(TicketModel ticket) {
+    }
+
+    @Override
+    public void onUpdateTicket(TicketModel ticket, Change change) {
+    }
+}
+```
+
 ### Mac OSX Fonts
 
 Gitblit's core SSH commands and those in the *powertools* plugin rely on use of ANSI border characters to provide a pretty presentation of data.  Unfortunately, the fonts provided by Apple - while very nice - don't work well with ANSI border characters.  The following public domain fixed-width, fixed-point, bitmapped fonts work very nicely.  I find the 6x12 font with a line spacing of ~0.8 to be quite acceptable.
diff --git a/src/test/java/com/gitblit/tests/BranchTicketServiceTest.java b/src/test/java/com/gitblit/tests/BranchTicketServiceTest.java
index 4bd74f5..6119b8d 100644
--- a/src/test/java/com/gitblit/tests/BranchTicketServiceTest.java
+++ b/src/test/java/com/gitblit/tests/BranchTicketServiceTest.java
@@ -17,10 +17,12 @@
 
 import com.gitblit.IStoredSettings;
 import com.gitblit.manager.INotificationManager;
+import com.gitblit.manager.IPluginManager;
 import com.gitblit.manager.IRepositoryManager;
 import com.gitblit.manager.IRuntimeManager;
 import com.gitblit.manager.IUserManager;
 import com.gitblit.manager.NotificationManager;
+import com.gitblit.manager.PluginManager;
 import com.gitblit.manager.RepositoryManager;
 import com.gitblit.manager.RuntimeManager;
 import com.gitblit.manager.UserManager;
@@ -50,12 +52,14 @@
 		IStoredSettings settings = getSettings(deleteAll);
 
 		IRuntimeManager runtimeManager = new RuntimeManager(settings).start();
+		IPluginManager pluginManager = new PluginManager(runtimeManager).start();
 		INotificationManager notificationManager = new NotificationManager(settings).start();
 		IUserManager userManager = new UserManager(runtimeManager).start();
 		IRepositoryManager repositoryManager = new RepositoryManager(runtimeManager, userManager).start();
 
 		BranchTicketService service = new BranchTicketService(
 				runtimeManager,
+				pluginManager,
 				notificationManager,
 				userManager,
 				repositoryManager).start();
diff --git a/src/test/java/com/gitblit/tests/FileTicketServiceTest.java b/src/test/java/com/gitblit/tests/FileTicketServiceTest.java
index 3cc2521..20cde26 100644
--- a/src/test/java/com/gitblit/tests/FileTicketServiceTest.java
+++ b/src/test/java/com/gitblit/tests/FileTicketServiceTest.java
@@ -17,10 +17,12 @@
 
 import com.gitblit.IStoredSettings;
 import com.gitblit.manager.INotificationManager;
+import com.gitblit.manager.IPluginManager;
 import com.gitblit.manager.IRepositoryManager;
 import com.gitblit.manager.IRuntimeManager;
 import com.gitblit.manager.IUserManager;
 import com.gitblit.manager.NotificationManager;
+import com.gitblit.manager.PluginManager;
 import com.gitblit.manager.RepositoryManager;
 import com.gitblit.manager.RuntimeManager;
 import com.gitblit.manager.UserManager;
@@ -49,12 +51,14 @@
 		IStoredSettings settings = getSettings(deleteAll);
 
 		IRuntimeManager runtimeManager = new RuntimeManager(settings).start();
+		IPluginManager pluginManager = new PluginManager(runtimeManager).start();
 		INotificationManager notificationManager = new NotificationManager(settings).start();
 		IUserManager userManager = new UserManager(runtimeManager).start();
 		IRepositoryManager repositoryManager = new RepositoryManager(runtimeManager, userManager).start();
 
 		FileTicketService service = new FileTicketService(
 				runtimeManager,
+				pluginManager,
 				notificationManager,
 				userManager,
 				repositoryManager).start();
diff --git a/src/test/java/com/gitblit/tests/RedisTicketServiceTest.java b/src/test/java/com/gitblit/tests/RedisTicketServiceTest.java
index 5a4bda7..94391a1 100644
--- a/src/test/java/com/gitblit/tests/RedisTicketServiceTest.java
+++ b/src/test/java/com/gitblit/tests/RedisTicketServiceTest.java
@@ -18,10 +18,12 @@
 import com.gitblit.IStoredSettings;
 import com.gitblit.Keys;
 import com.gitblit.manager.INotificationManager;
+import com.gitblit.manager.IPluginManager;
 import com.gitblit.manager.IRepositoryManager;
 import com.gitblit.manager.IRuntimeManager;
 import com.gitblit.manager.IUserManager;
 import com.gitblit.manager.NotificationManager;
+import com.gitblit.manager.PluginManager;
 import com.gitblit.manager.RepositoryManager;
 import com.gitblit.manager.RuntimeManager;
 import com.gitblit.manager.UserManager;
@@ -57,12 +59,14 @@
 		IStoredSettings settings = getSettings(deleteAll);
 
 		IRuntimeManager runtimeManager = new RuntimeManager(settings).start();
+		IPluginManager pluginManager = new PluginManager(runtimeManager).start();
 		INotificationManager notificationManager = new NotificationManager(settings).start();
 		IUserManager userManager = new UserManager(runtimeManager).start();
 		IRepositoryManager repositoryManager = new RepositoryManager(runtimeManager, userManager).start();
 
 		RedisTicketService service = new RedisTicketService(
 				runtimeManager,
+				pluginManager,
 				notificationManager,
 				userManager,
 				repositoryManager).start();

--
Gitblit v1.9.1