From 9d921f83d48fff71762bb4a579870107c788ecf9 Mon Sep 17 00:00:00 2001
From: James Moger <james.moger@gitblit.com>
Date: Fri, 24 Feb 2012 17:34:31 -0500
Subject: Activity page now considers all local branches (issue 65)

---
 src/com/gitblit/models/Activity.java             | 65 +++++++++++++----
 src/com/gitblit/utils/ActivityUtils.java         | 89 +++++++++++-------------
 src/com/gitblit/wicket/pages/ActivityPage.java   |  4 +-
 src/com/gitblit/wicket/panels/ActivityPanel.java |  3 +-
 4 files changed, 97 insertions(+), 64 deletions(-)

(limited to 'src/com')

diff --git a/src/com/gitblit/models/Activity.java b/src/com/gitblit/models/Activity.java
index f24a5abe..9d58ef07 100644
--- a/src/com/gitblit/models/Activity.java
+++ b/src/com/gitblit/models/Activity.java
@@ -17,10 +17,13 @@ package com.gitblit.models;
 
 import java.io.Serializable;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import org.eclipse.jgit.lib.PersonIdent;
 import org.eclipse.jgit.revwalk.RevCommit;
@@ -41,7 +44,7 @@ public class Activity implements Serializable, Comparable<Activity> {
 
 	public final Date endDate;
 
-	public final List<RepositoryCommit> commits;
+	private final Set<RepositoryCommit> commits;
 
 	private final Map<String, Metric> authorMetrics;
 
@@ -67,26 +70,48 @@ public class Activity implements Serializable, Comparable<Activity> {
 	public Activity(Date date, long duration) {
 		startDate = date;
 		endDate = new Date(date.getTime() + duration);
-		commits = new ArrayList<RepositoryCommit>();
+		commits = new LinkedHashSet<RepositoryCommit>();
 		authorMetrics = new HashMap<String, Metric>();
 		repositoryMetrics = new HashMap<String, Metric>();
 	}
 
+	/**
+	 * Adds a commit to the activity object as long as the commit is not a
+	 * duplicate.
+	 * 
+	 * @param repository
+	 * @param branch
+	 * @param commit
+	 * @return a RepositoryCommit, if one was added. Null if this is duplicate
+	 *         commit
+	 */
 	public RepositoryCommit addCommit(String repository, String branch, RevCommit commit) {
 		RepositoryCommit commitModel = new RepositoryCommit(repository, branch, commit);
-		commits.add(commitModel);
-
-		if (!repositoryMetrics.containsKey(repository)) {
-			repositoryMetrics.put(repository, new Metric(repository));
-		}
-		repositoryMetrics.get(repository).count++;
+		if (commits.add(commitModel)) {
+			if (!repositoryMetrics.containsKey(repository)) {
+				repositoryMetrics.put(repository, new Metric(repository));
+			}
+			repositoryMetrics.get(repository).count++;
 
-		String author = commit.getAuthorIdent().getEmailAddress().toLowerCase();
-		if (!authorMetrics.containsKey(author)) {
-			authorMetrics.put(author, new Metric(author));
+			String author = commit.getAuthorIdent().getEmailAddress()
+					.toLowerCase();
+			if (!authorMetrics.containsKey(author)) {
+				authorMetrics.put(author, new Metric(author));
+			}
+			authorMetrics.get(author).count++;
+			return commitModel;
 		}
-		authorMetrics.get(author).count++;
-		return commitModel;
+		return null;
+	}
+	
+	public int getCommitCount() {
+		return commits.size();
+	}
+	
+	public List<RepositoryCommit> getCommits() {
+		List<RepositoryCommit> list = new ArrayList<RepositoryCommit>(commits);
+		Collections.sort(list);
+		return list;
 	}
 
 	public Map<String, Metric> getAuthorMetrics() {
@@ -154,6 +179,20 @@ public class Activity implements Serializable, Comparable<Activity> {
 		public PersonIdent getAuthorIdent() {
 			return commit.getAuthorIdent();
 		}
+		
+		@Override
+		public boolean equals(Object o) {
+			if (o instanceof RepositoryCommit) {
+				RepositoryCommit commit = (RepositoryCommit) o;
+				return repository.equals(commit.repository) && getName().equals(commit.getName());
+			}
+			return false;
+		}
+		
+		@Override
+		public int hashCode() {
+			return (repository + commit).hashCode();
+		}
 
 		@Override
 		public int compareTo(RepositoryCommit o) {
diff --git a/src/com/gitblit/utils/ActivityUtils.java b/src/com/gitblit/utils/ActivityUtils.java
index d6afd93c..61b6242a 100644
--- a/src/com/gitblit/utils/ActivityUtils.java
+++ b/src/com/gitblit/utils/ActivityUtils.java
@@ -23,7 +23,6 @@ import java.text.MessageFormat;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Calendar;
-import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
@@ -59,8 +58,8 @@ public class ActivityUtils {
 	 * @param daysBack
 	 *            the number of days back from Now to collect
 	 * @param objectId
-	 *            the branch to retrieve. If this value is null the default
-	 *            branch of the repository is used.
+	 *            the branch to retrieve. If this value is null or empty all
+	 *            branches are queried.
 	 * @return
 	 */
 	public static List<Activity> getRecentActivity(List<RepositoryModel> models, int daysBack,
@@ -73,64 +72,60 @@ public class ActivityUtils {
 		// Build a map of DailyActivity from the available repositories for the
 		// specified threshold date.
 		DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
+		df.setTimeZone(GitBlit.getTimezone());
 		Calendar cal = Calendar.getInstance();
+		cal.setTimeZone(GitBlit.getTimezone());
 
 		Map<String, Activity> activity = new HashMap<String, Activity>();
 		for (RepositoryModel model : models) {
 			if (model.hasCommits && model.lastChange.after(thresholdDate)) {
-				Repository repository = GitBlit.self().getRepository(model.name);
-				List<RevCommit> commits = JGitUtils.getRevLog(repository, objectId, thresholdDate);
-				Map<ObjectId, List<RefModel>> allRefs = JGitUtils.getAllRefs(repository);
-				repository.close();
-
-				// determine commit branch
-				String branch = objectId;
-				if (StringUtils.isEmpty(branch) && !commits.isEmpty()) {
-					List<RefModel> headRefs = allRefs.get(commits.get(0).getId());
-					List<String> localBranches = new ArrayList<String>();
-					for (RefModel ref : headRefs) {
-						if (ref.getName().startsWith(Constants.R_HEADS)) {
-							localBranches.add(ref.getName().substring(Constants.R_HEADS.length()));
-						}
-					}
-					// determine branch
-					if (localBranches.size() == 1) {
-						// only one branch, choose it
-						branch = localBranches.get(0);
-					} else if (localBranches.size() > 1) {
-						if (localBranches.contains("master")) {
-							// choose master
-							branch = "master";
-						} else {
-							// choose first branch
-							branch = localBranches.get(0);
-						}
+				Repository repository = GitBlit.self()
+						.getRepository(model.name);
+				List<String> branches = new ArrayList<String>();
+				if (StringUtils.isEmpty(objectId)) {
+					for (RefModel local : JGitUtils.getLocalBranches(
+							repository, true, -1)) {
+						branches.add(local.getName());
 					}
+				} else {
+					branches.add(objectId);
 				}
+				Map<ObjectId, List<RefModel>> allRefs = JGitUtils
+						.getAllRefs(repository);
 
-				for (RevCommit commit : commits) {
-					Date date = JGitUtils.getCommitDate(commit);
-					String dateStr = df.format(date);
-					if (!activity.containsKey(dateStr)) {
-						// Normalize the date to midnight
-						cal.setTime(date);
-						cal.set(Calendar.HOUR_OF_DAY, 0);
-						cal.set(Calendar.MINUTE, 0);
-						cal.set(Calendar.SECOND, 0);
-						cal.set(Calendar.MILLISECOND, 0);
-						activity.put(dateStr, new Activity(cal.getTime()));
+				for (String branch : branches) {
+					String shortName = branch;
+					if (shortName.startsWith(Constants.R_HEADS)) {
+						shortName = shortName.substring(Constants.R_HEADS.length());
+					}
+					List<RevCommit> commits = JGitUtils.getRevLog(repository,
+							branch, thresholdDate);
+					for (RevCommit commit : commits) {
+						Date date = JGitUtils.getCommitDate(commit);
+						String dateStr = df.format(date);
+						if (!activity.containsKey(dateStr)) {
+							// Normalize the date to midnight
+							cal.setTime(date);
+							cal.set(Calendar.HOUR_OF_DAY, 0);
+							cal.set(Calendar.MINUTE, 0);
+							cal.set(Calendar.SECOND, 0);
+							cal.set(Calendar.MILLISECOND, 0);
+							activity.put(dateStr, new Activity(cal.getTime()));
+						}
+						RepositoryCommit commitModel = activity.get(dateStr)
+								.addCommit(model.name, shortName, commit);
+						if (commitModel != null) {
+							commitModel.setRefs(allRefs.get(commit.getId()));
+						}
 					}
-					RepositoryCommit commitModel = activity.get(dateStr).addCommit(model.name,
-							branch, commit);
-					commitModel.setRefs(allRefs.get(commit.getId()));
 				}
+				
+				// close the repository
+				repository.close();
 			}
 		}
 
 		List<Activity> recentActivity = new ArrayList<Activity>(activity.values());
-		for (Activity daily : recentActivity) {
-			Collections.sort(daily.commits);
-		}
 		return recentActivity;
 	}
 
diff --git a/src/com/gitblit/wicket/pages/ActivityPage.java b/src/com/gitblit/wicket/pages/ActivityPage.java
index 634b2985..e59e68ee 100644
--- a/src/com/gitblit/wicket/pages/ActivityPage.java
+++ b/src/com/gitblit/wicket/pages/ActivityPage.java
@@ -79,7 +79,7 @@ public class ActivityPage extends RootPage {
 			int totalCommits = 0;
 			Set<String> uniqueAuthors = new HashSet<String>();
 			for (Activity activity : recentActivity) {
-				totalCommits += activity.commits.size();
+				totalCommits += activity.getCommitCount();
 				uniqueAuthors.addAll(activity.getAuthorMetrics().keySet());
 			}
 			int totalAuthors = uniqueAuthors.size();
@@ -174,7 +174,7 @@ public class ActivityPage extends RootPage {
 				getString("gb.commits"));
 		SimpleDateFormat df = new SimpleDateFormat("MMM dd");
 		for (Activity metric : recentActivity) {
-			chart.addValue(df.format(metric.startDate), metric.commits.size());
+			chart.addValue(df.format(metric.startDate), metric.getCommitCount());
 		}
 		chart.setWidth(w);
 		chart.setHeight(h);
diff --git a/src/com/gitblit/wicket/panels/ActivityPanel.java b/src/com/gitblit/wicket/panels/ActivityPanel.java
index 45486195..34a281fb 100644
--- a/src/com/gitblit/wicket/panels/ActivityPanel.java
+++ b/src/com/gitblit/wicket/panels/ActivityPanel.java
@@ -28,7 +28,6 @@ import com.gitblit.Constants;
 import com.gitblit.models.Activity;
 import com.gitblit.models.Activity.RepositoryCommit;
 import com.gitblit.utils.StringUtils;
-import com.gitblit.wicket.GitBlitWebSession;
 import com.gitblit.wicket.WicketUtils;
 import com.gitblit.wicket.pages.CommitDiffPage;
 import com.gitblit.wicket.pages.CommitPage;
@@ -62,7 +61,7 @@ public class ActivityPanel extends BasePanel {
 
 				// display the commits in chronological order
 				DataView<RepositoryCommit> commits = new DataView<RepositoryCommit>("commits",
-						new ListDataProvider<RepositoryCommit>(entry.commits)) {
+						new ListDataProvider<RepositoryCommit>(entry.getCommits())) {
 					private static final long serialVersionUID = 1L;
 
 					public void populateItem(final Item<RepositoryCommit> item) {
-- 
cgit v1.2.3