From f76fee63ed9cb3a30d3c0c092d860b1cb93a481b Mon Sep 17 00:00:00 2001
From: Gerard Smyth <gerard.smyth@gmail.com>
Date: Thu, 08 May 2014 13:09:30 -0400
Subject: [PATCH] Updated the SyndicationServlet to provide an additional option to return details of the tags in the repository instead of the commits. This uses a new 'ot' request parameter to indicate the object type of the content to return, which can be ither TAG or COMMIT. If this is not provided, then COMMIT is assumed to maintain backwards compatability. If tags are returned, then the paging parameters, 'l' and 'pg' are still supported, but searching options are currently ignored.

---
 src/main/java/com/gitblit/tickets/BranchTicketService.java |  112 +++++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 95 insertions(+), 17 deletions(-)

diff --git a/src/main/java/com/gitblit/tickets/BranchTicketService.java b/src/main/java/com/gitblit/tickets/BranchTicketService.java
index a25dac8..8c00055 100644
--- a/src/main/java/com/gitblit/tickets/BranchTicketService.java
+++ b/src/main/java/com/gitblit/tickets/BranchTicketService.java
@@ -43,6 +43,8 @@
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.ObjectInserter;
 import org.eclipse.jgit.lib.PersonIdent;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.RefRename;
 import org.eclipse.jgit.lib.RefUpdate;
 import org.eclipse.jgit.lib.RefUpdate.Result;
 import org.eclipse.jgit.lib.Repository;
@@ -56,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;
@@ -80,7 +83,7 @@
  */
 public class BranchTicketService extends ITicketService implements RefsChangedListener {
 
-	public static final String BRANCH = "refs/gitblit/tickets";
+	public static final String BRANCH = "refs/meta/gitblit/tickets";
 
 	private static final String JOURNAL = "journal.json";
 
@@ -90,11 +93,13 @@
 
 	public BranchTicketService(
 			IRuntimeManager runtimeManager,
+			IPluginManager pluginManager,
 			INotificationManager notificationManager,
 			IUserManager userManager,
 			IRepositoryManager repositoryManager) {
 
 		super(runtimeManager,
+				pluginManager,
 				notificationManager,
 				userManager,
 				repositoryManager);
@@ -187,23 +192,45 @@
 	}
 
 	/**
-	 * Returns a RefModel for the refs/gitblit/tickets branch in the repository.
+	 * Returns a RefModel for the refs/meta/gitblit/tickets branch in the repository.
 	 * If the branch can not be found, null is returned.
 	 *
 	 * @return a refmodel for the gitblit tickets branch or null
 	 */
 	private RefModel getTicketsBranch(Repository db) {
-		List<RefModel> refs = JGitUtils.getRefs(db, Constants.R_GITBLIT);
+		List<RefModel> refs = JGitUtils.getRefs(db, "refs/");
+		Ref oldRef = null;
 		for (RefModel ref : refs) {
 			if (ref.reference.getName().equals(BRANCH)) {
 				return ref;
+			} else if (ref.reference.getName().equals("refs/gitblit/tickets")) {
+				oldRef = ref.reference;
+			}
+		}
+		if (oldRef != null) {
+			// rename old ref to refs/meta/gitblit/tickets
+			RefRename cmd;
+			try {
+				cmd = db.renameRef(oldRef.getName(), BRANCH);
+				cmd.setRefLogIdent(new PersonIdent("Gitblit", "gitblit@localhost"));
+				cmd.setRefLogMessage("renamed " + oldRef.getName() + " => " + BRANCH);
+				Result res = cmd.rename();
+				switch (res) {
+				case RENAMED:
+					log.info(db.getDirectory() + " " + cmd.getRefLogMessage());
+					return getTicketsBranch(db);
+				default:
+					log.error("failed to rename " + oldRef.getName() + " => " + BRANCH + " (" + res.name() + ")");
+				}
+			} catch (IOException e) {
+				log.error("failed to rename tickets branch", e);
 			}
 		}
 		return null;
 	}
 
 	/**
-	 * Creates the refs/gitblit/tickets branch.
+	 * Creates the refs/meta/gitblit/tickets branch.
 	 * @param db
 	 */
 	private void createTicketsBranch(Repository db) {
@@ -216,7 +243,7 @@
 	 * folder with the remaining characters as a subfolder within that folder.
 	 *
 	 * @param ticketId
-	 * @return the root path of the ticket content on the refs/gitblit/tickets branch
+	 * @return the root path of the ticket content on the refs/meta/gitblit/tickets branch
 	 */
 	private String toTicketPath(long ticketId) {
 		StringBuilder sb = new StringBuilder();
@@ -351,6 +378,37 @@
 	}
 
 	/**
+	 * Returns the assigned ticket ids.
+	 *
+	 * @return the assigned ticket ids
+	 */
+	@Override
+	public synchronized Set<Long> getIds(RepositoryModel repository) {
+		Repository db = repositoryManager.getRepository(repository.name);
+		try {
+			if (getTicketsBranch(db) == null) {
+				return Collections.emptySet();
+			}
+			Set<Long> ids = new TreeSet<Long>();
+			List<PathModel> paths = JGitUtils.getDocuments(db, Arrays.asList("json"), BRANCH);
+			for (PathModel path : paths) {
+				String name = path.name.substring(path.name.lastIndexOf('/') + 1);
+				if (!JOURNAL.equals(name)) {
+					continue;
+				}
+				String tid = path.path.split("/")[2];
+				long ticketId = Long.parseLong(tid);
+				ids.add(ticketId);
+			}
+			return ids;
+		} finally {
+			if (db != null) {
+				db.close();
+			}
+		}
+	}
+
+	/**
 	 * Assigns a new ticket id.
 	 *
 	 * @param repository
@@ -371,16 +429,10 @@
 			}
 			AtomicLong lastId = lastAssignedId.get(repository.name);
 			if (lastId.get() <= 0) {
-				List<PathModel> paths = JGitUtils.getDocuments(db, Arrays.asList("json"), BRANCH);
-				for (PathModel path : paths) {
-					String name = path.name.substring(path.name.lastIndexOf('/') + 1);
-					if (!JOURNAL.equals(name)) {
-						continue;
-					}
-					String tid = path.path.split("/")[2];
-					long ticketId = Long.parseLong(tid);
-					if (ticketId > lastId.get()) {
-						lastId.set(ticketId);
+				Set<Long> ids = getIds(repository);
+				for (long id : ids) {
+					if (id > lastId.get()) {
+						lastId.set(id);
 					}
 				}
 			}
@@ -493,6 +545,28 @@
 				ticket.number = ticketId;
 			}
 			return ticket;
+		} finally {
+			db.close();
+		}
+	}
+
+	/**
+	 * Retrieves the journal for the ticket.
+	 *
+	 * @param repository
+	 * @param ticketId
+	 * @return a journal, if it exists, otherwise null
+	 */
+	@Override
+	protected List<Change> getJournalImpl(RepositoryModel repository, long ticketId) {
+		Repository db = repositoryManager.getRepository(repository.name);
+		try {
+			List<Change> changes = getJournal(db, ticketId);
+			if (ArrayUtils.isEmpty(changes)) {
+				log.warn("Empty journal for {}:{}", repository, ticketId);
+				return null;
+			}
+			return changes;
 		} finally {
 			db.close();
 		}
@@ -632,7 +706,9 @@
 						ticket.number, db.getDirectory()), t);
 			} finally {
 				// release the treewalk
-				treeWalk.release();
+				if (treeWalk != null) {
+					treeWalk.release();
+				}
 			}
 		} finally {
 			db.close();
@@ -848,7 +924,9 @@
 		} catch (Exception e) {
 			log.error(null, e);
 		} finally {
-			db.close();
+			if (db != null) {
+				db.close();
+			}
 		}
 		return false;
 	}

--
Gitblit v1.9.1