From d9f68798555e5ba8b4f7ddecf4a8cabbe9bb161a Mon Sep 17 00:00:00 2001
From: James Moger <james.moger@gitblit.com>
Date: Fri, 01 Jul 2011 21:17:28 -0400
Subject: [PATCH] Documentation. Added JavaDoc comments.

---
 src/com/gitblit/models/Metric.java              |    9 
 src/com/gitblit/utils/StringUtils.java          |  137 +++++++++++
 src/com/gitblit/utils/TimeUtils.java            |   76 ++++++
 src/com/gitblit/utils/MarkdownUtils.java        |   21 +
 src/com/gitblit/models/RefModel.java            |    7 
 src/com/gitblit/utils/ByteFormat.java           |    7 
 src/com/gitblit/utils/PatchFormatter.java       |    6 
 src/com/gitblit/models/TicketModel.java         |   51 ++-
 src/com/gitblit/utils/FileUtils.java            |    2 
 src/com/gitblit/models/UserModel.java           |    8 
 src/com/gitblit/utils/GitWebDiffFormatter.java  |    6 
 src/com/gitblit/utils/SyndicationUtils.java     |   18 +
 src/com/gitblit/utils/DiffUtils.java            |  161 +++++++++----
 src/com/gitblit/utils/GitBlitDiffFormatter.java |    6 
 src/com/gitblit/models/PathModel.java           |   14 +
 src/com/gitblit/utils/TicgitUtils.java          |   62 ++++-
 src/com/gitblit/models/RepositoryModel.java     |    7 
 src/com/gitblit/utils/MetricUtils.java          |   74 ++++-
 src/com/gitblit/models/AnnotatedLine.java       |    7 
 src/com/gitblit/models/GitNote.java             |   12 
 20 files changed, 588 insertions(+), 103 deletions(-)

diff --git a/src/com/gitblit/models/AnnotatedLine.java b/src/com/gitblit/models/AnnotatedLine.java
index 3d12476..69b55bc 100644
--- a/src/com/gitblit/models/AnnotatedLine.java
+++ b/src/com/gitblit/models/AnnotatedLine.java
@@ -20,6 +20,13 @@
 
 import org.eclipse.jgit.revwalk.RevCommit;
 
+/**
+ * AnnotatedLine is a serializable model class that represents a the most recent
+ * author, date, and commit id of a line in a source file.
+ * 
+ * @author James Moger
+ * 
+ */
 public class AnnotatedLine implements Serializable {
 
 	private static final long serialVersionUID = 1L;
diff --git a/src/com/gitblit/models/GitNote.java b/src/com/gitblit/models/GitNote.java
index 3b66d89..c333a88 100644
--- a/src/com/gitblit/models/GitNote.java
+++ b/src/com/gitblit/models/GitNote.java
@@ -17,12 +17,20 @@
 
 import java.io.Serializable;
 
+/**
+ * GitNote is a serializable model class that represents a git note. This class
+ * retains an instance of the RefModel which contains the commit in which this
+ * git note was created.
+ * 
+ * @author James Moger
+ * 
+ */
 public class GitNote implements Serializable {
 
 	private static final long serialVersionUID = 1L;
 
-	public String content;
-	public RefModel notesRef;
+	public final String content;
+	public final RefModel notesRef;
 
 	public GitNote(RefModel notesRef, String text) {
 		this.notesRef = notesRef;
diff --git a/src/com/gitblit/models/Metric.java b/src/com/gitblit/models/Metric.java
index 9ff270a..e7c49a4 100644
--- a/src/com/gitblit/models/Metric.java
+++ b/src/com/gitblit/models/Metric.java
@@ -17,11 +17,18 @@
 
 import java.io.Serializable;
 
+/**
+ * Metric is a serializable model class that encapsulates metrics for some given
+ * type.
+ * 
+ * @author James Moger
+ * 
+ */
 public class Metric implements Serializable {
 
 	private static final long serialVersionUID = 1L;
 
-	public String name;
+	public final String name;
 	public double count;
 	public double tag;
 	public int duration;
diff --git a/src/com/gitblit/models/PathModel.java b/src/com/gitblit/models/PathModel.java
index 0841531..c78b300 100644
--- a/src/com/gitblit/models/PathModel.java
+++ b/src/com/gitblit/models/PathModel.java
@@ -20,6 +20,13 @@
 import org.eclipse.jgit.diff.DiffEntry.ChangeType;
 import org.eclipse.jgit.lib.FileMode;
 
+/**
+ * PathModel is a serializable model class that represents a file or a folder,
+ * including all its metadata and associated commit id.
+ * 
+ * @author James Moger
+ * 
+ */
 public class PathModel implements Serializable, Comparable<PathModel> {
 
 	private static final long serialVersionUID = 1L;
@@ -71,6 +78,13 @@
 		return 1;
 	}
 
+	/**
+	 * PathChangeModel is a serializable class that represents a file changed in
+	 * a commit.
+	 * 
+	 * @author James Moger
+	 * 
+	 */
 	public static class PathChangeModel extends PathModel {
 
 		private static final long serialVersionUID = 1L;
diff --git a/src/com/gitblit/models/RefModel.java b/src/com/gitblit/models/RefModel.java
index 92c394c..fab5fc1 100644
--- a/src/com/gitblit/models/RefModel.java
+++ b/src/com/gitblit/models/RefModel.java
@@ -25,6 +25,13 @@
 import org.eclipse.jgit.revwalk.RevObject;
 import org.eclipse.jgit.revwalk.RevTag;
 
+/**
+ * RefModel is a serializable model class that represents a tag or branch and
+ * includes the referenced object.
+ * 
+ * @author James Moger
+ * 
+ */
 public class RefModel implements Serializable, Comparable<RefModel> {
 
 	private static final long serialVersionUID = 1L;
diff --git a/src/com/gitblit/models/RepositoryModel.java b/src/com/gitblit/models/RepositoryModel.java
index 97ae518..3863737 100644
--- a/src/com/gitblit/models/RepositoryModel.java
+++ b/src/com/gitblit/models/RepositoryModel.java
@@ -20,6 +20,13 @@
 
 import com.gitblit.Constants.AccessRestrictionType;
 
+/**
+ * RepositoryModel is a serializable model class that represents a Gitblit
+ * repository including its configuration settings and access restriction.
+ * 
+ * @author James Moger
+ * 
+ */
 public class RepositoryModel implements Serializable {
 
 	private static final long serialVersionUID = 1L;
diff --git a/src/com/gitblit/models/TicketModel.java b/src/com/gitblit/models/TicketModel.java
index d86a073..b8043c6 100644
--- a/src/com/gitblit/models/TicketModel.java
+++ b/src/com/gitblit/models/TicketModel.java
@@ -21,6 +21,12 @@
 import java.util.Date;
 import java.util.List;
 
+/**
+ * TicketModel is a serializable model class that represents a Ticgit ticket.
+ * 
+ * @author James Moger
+ * 
+ */
 public class TicketModel implements Serializable, Comparable<TicketModel> {
 
 	private static final long serialVersionUID = 1L;
@@ -50,6 +56,32 @@
 		}
 	}
 
+	@Override
+	public int hashCode() {
+		return id.hashCode();
+	}
+
+	@Override
+	public boolean equals(Object o) {
+		if (o instanceof TicketModel) {
+			TicketModel other = (TicketModel) o;
+			return id.equals(other.id);
+		}
+		return super.equals(o);
+	}
+
+	@Override
+	public int compareTo(TicketModel o) {
+		return date.compareTo(o.date);
+	}
+
+	/**
+	 * Comment is a serializable model class that represents a Ticgit ticket
+	 * comment.
+	 * 
+	 * @author James Moger
+	 * 
+	 */
 	public static class Comment implements Serializable, Comparable<Comment> {
 
 		private static final long serialVersionUID = 1L;
@@ -83,24 +115,5 @@
 		public int compareTo(Comment o) {
 			return date.compareTo(o.date);
 		}
-	}
-
-	@Override
-	public int hashCode() {
-		return id.hashCode();
-	}
-
-	@Override
-	public boolean equals(Object o) {
-		if (o instanceof TicketModel) {
-			TicketModel other = (TicketModel) o;
-			return id.equals(other.id);
-		}
-		return super.equals(o);
-	}
-
-	@Override
-	public int compareTo(TicketModel o) {
-		return date.compareTo(o.date);
 	}
 }
diff --git a/src/com/gitblit/models/UserModel.java b/src/com/gitblit/models/UserModel.java
index fd355fb..aeeecf4 100644
--- a/src/com/gitblit/models/UserModel.java
+++ b/src/com/gitblit/models/UserModel.java
@@ -20,6 +20,14 @@
 import java.util.ArrayList;
 import java.util.List;
 
+/**
+ * UserModel is a serializable model class that represents a user and the user's
+ * restricted repository memberships. Instances of UserModels are also used as
+ * servlet user principals.
+ * 
+ * @author James Moger
+ * 
+ */
 public class UserModel implements Principal, Serializable {
 
 	private static final long serialVersionUID = 1L;
diff --git a/src/com/gitblit/utils/ByteFormat.java b/src/com/gitblit/utils/ByteFormat.java
index ea198de..f4c05cd 100644
--- a/src/com/gitblit/utils/ByteFormat.java
+++ b/src/com/gitblit/utils/ByteFormat.java
@@ -20,6 +20,13 @@
 import java.text.Format;
 import java.text.ParsePosition;
 
+/**
+ * ByteFormat is a formatter which takes numbers and returns filesizes in bytes,
+ * kilobytes, megabytes, or gigabytes.
+ * 
+ * @author James Moger
+ * 
+ */
 public class ByteFormat extends Format {
 
 	private static final long serialVersionUID = 1L;
diff --git a/src/com/gitblit/utils/DiffUtils.java b/src/com/gitblit/utils/DiffUtils.java
index c1401f9..beeb532 100644
--- a/src/com/gitblit/utils/DiffUtils.java
+++ b/src/com/gitblit/utils/DiffUtils.java
@@ -30,13 +30,20 @@
 import org.eclipse.jgit.revwalk.RevCommit;
 import org.eclipse.jgit.revwalk.RevTree;
 import org.eclipse.jgit.revwalk.RevWalk;
-import org.eclipse.jgit.treewalk.TreeWalk;
-import org.eclipse.jgit.treewalk.filter.TreeFilter;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.gitblit.models.AnnotatedLine;
 
+/**
+ * DiffUtils is a class of utility methods related to diff, patch, and blame.
+ * 
+ * The diff methods support pluggable diff output types like Gitblit, Gitweb,
+ * and Plain.
+ * 
+ * @author James Moger
+ * 
+ */
 public class DiffUtils {
 
 	private static final Logger LOGGER = LoggerFactory.getLogger(DiffUtils.class);
@@ -54,43 +61,67 @@
 		}
 	}
 
-	public static String getCommitDiff(Repository r, RevCommit commit, DiffOutputType outputType) {
-		return getDiff(r, null, commit, null, outputType);
+	/**
+	 * Returns the complete diff of the specified commit compared to its primary
+	 * parent.
+	 * 
+	 * @param repository
+	 * @param commit
+	 * @param outputType
+	 * @return the diff as a string
+	 */
+	public static String getCommitDiff(Repository repository, RevCommit commit,
+			DiffOutputType outputType) {
+		return getDiff(repository, null, commit, null, outputType);
 	}
 
-	public static String getDiff(Repository r, RevCommit commit, String path,
+	/**
+	 * Returns the diff for the specified file or folder from the specified
+	 * commit compared to its primary parent.
+	 * 
+	 * @param repository
+	 * @param commit
+	 * @param path
+	 * @param outputType
+	 * @return the diff as a string
+	 */
+	public static String getDiff(Repository repository, RevCommit commit, String path,
 			DiffOutputType outputType) {
-		return getDiff(r, null, commit, path, outputType);
+		return getDiff(repository, null, commit, path, outputType);
 	}
 
-	public static String getDiff(Repository r, RevCommit baseCommit, RevCommit commit,
+	/**
+	 * Returns the complete diff between the two specified commits.
+	 * 
+	 * @param repository
+	 * @param baseCommit
+	 * @param commit
+	 * @param outputType
+	 * @return the diff as a string
+	 */
+	public static String getDiff(Repository repository, RevCommit baseCommit, RevCommit commit,
 			DiffOutputType outputType) {
-		return getDiff(r, baseCommit, commit, null, outputType);
+		return getDiff(repository, baseCommit, commit, null, outputType);
 	}
 
-	public static String getDiff(Repository r, RevCommit baseCommit, RevCommit commit, String path,
-			DiffOutputType outputType) {
+	/**
+	 * Returns the diff between two commits for the specified file.
+	 * 
+	 * @param repository
+	 * @param baseCommit
+	 *            if base commit is null the diff is to the primary parent of
+	 *            the commit.
+	 * @param commit
+	 * @param path
+	 *            if the path is specified, the diff is restricted to that file
+	 *            or folder. if unspecified, the diff is for the entire commit.
+	 * @param outputType
+	 * @return the diff as a string
+	 */
+	public static String getDiff(Repository repository, RevCommit baseCommit, RevCommit commit,
+			String path, DiffOutputType outputType) {
 		String diff = null;
 		try {
-			RevTree baseTree;
-			if (baseCommit == null) {
-				final RevWalk rw = new RevWalk(r);
-				RevCommit parent = rw.parseCommit(commit.getParent(0).getId());
-				rw.dispose();
-				baseTree = parent.getTree();
-			} else {
-				baseTree = baseCommit.getTree();
-			}
-
-			RevTree commitTree = commit.getTree();
-
-			final TreeWalk walk = new TreeWalk(r);
-			walk.reset();
-			walk.setRecursive(true);
-			walk.addTree(baseTree);
-			walk.addTree(commitTree);
-			walk.setFilter(TreeFilter.ANY_DIFF);
-
 			final ByteArrayOutputStream os = new ByteArrayOutputStream();
 			RawTextComparator cmp = RawTextComparator.DEFAULT;
 			DiffFormatter df;
@@ -106,9 +137,21 @@
 				df = new DiffFormatter(os);
 				break;
 			}
-			df.setRepository(r);
+			df.setRepository(repository);
 			df.setDiffComparator(cmp);
 			df.setDetectRenames(true);
+
+			RevTree commitTree = commit.getTree();
+			RevTree baseTree;
+			if (baseCommit == null) {
+				final RevWalk rw = new RevWalk(repository);
+				RevCommit parent = rw.parseCommit(commit.getParent(0).getId());
+				rw.dispose();
+				baseTree = parent.getTree();
+			} else {
+				baseTree = baseCommit.getTree();
+			}
+
 			List<DiffEntry> diffEntries = df.scan(baseTree, commitTree);
 			if (path != null && path.length() > 0) {
 				for (DiffEntry diffEntry : diffEntries) {
@@ -133,33 +176,42 @@
 		return diff;
 	}
 
-	public static String getCommitPatch(Repository r, RevCommit baseCommit, RevCommit commit,
-			String path) {
+	/**
+	 * Returns the diff between the two commits for the specified file or folder
+	 * formatted as a patch.
+	 * 
+	 * @param repository
+	 * @param baseCommit
+	 *            if base commit is unspecified, the patch is generated against
+	 *            the primary parent of the specified commit.
+	 * @param commit
+	 * @param path
+	 *            if path is specified, the patch is generated only for the
+	 *            specified file or folder. if unspecified, the patch is
+	 *            generated for the entire diff between the two commits.
+	 * @return patch as a string
+	 */
+	public static String getCommitPatch(Repository repository, RevCommit baseCommit,
+			RevCommit commit, String path) {
 		String diff = null;
 		try {
+			final ByteArrayOutputStream os = new ByteArrayOutputStream();
+			RawTextComparator cmp = RawTextComparator.DEFAULT;
+			PatchFormatter df = new PatchFormatter(os);
+			df.setRepository(repository);
+			df.setDiffComparator(cmp);
+			df.setDetectRenames(true);
+
+			RevTree commitTree = commit.getTree();
 			RevTree baseTree;
 			if (baseCommit == null) {
-				final RevWalk rw = new RevWalk(r);
+				final RevWalk rw = new RevWalk(repository);
 				RevCommit parent = rw.parseCommit(commit.getParent(0).getId());
 				baseTree = parent.getTree();
 			} else {
 				baseTree = baseCommit.getTree();
 			}
-			RevTree commitTree = commit.getTree();
 
-			final TreeWalk walk = new TreeWalk(r);
-			walk.reset();
-			walk.setRecursive(true);
-			walk.addTree(baseTree);
-			walk.addTree(commitTree);
-			walk.setFilter(TreeFilter.ANY_DIFF);
-
-			final ByteArrayOutputStream os = new ByteArrayOutputStream();
-			RawTextComparator cmp = RawTextComparator.DEFAULT;
-			PatchFormatter df = new PatchFormatter(os);
-			df.setRepository(r);
-			df.setDiffComparator(cmp);
-			df.setDetectRenames(true);
 			List<DiffEntry> diffEntries = df.scan(baseTree, commitTree);
 			if (path != null && path.length() > 0) {
 				for (DiffEntry diffEntry : diffEntries) {
@@ -179,15 +231,24 @@
 		return diff;
 	}
 
-	public static List<AnnotatedLine> blame(Repository r, String blobPath, String objectId) {
+	/**
+	 * Returns the list of lines in the specified source file annotated with the
+	 * source commit metadata.
+	 * 
+	 * @param repository
+	 * @param blobPath
+	 * @param objectId
+	 * @return list of annotated lines
+	 */
+	public static List<AnnotatedLine> blame(Repository repository, String blobPath, String objectId) {
 		List<AnnotatedLine> lines = new ArrayList<AnnotatedLine>();
 		try {
 			if (StringUtils.isEmpty(objectId)) {
 				objectId = Constants.HEAD;
 			}
-			BlameCommand blameCommand = new BlameCommand(r);
+			BlameCommand blameCommand = new BlameCommand(repository);
 			blameCommand.setFilePath(blobPath);
-			blameCommand.setStartCommit(r.resolve(objectId));
+			blameCommand.setStartCommit(repository.resolve(objectId));
 			BlameResult blameResult = blameCommand.call();
 			RawText rawText = blameResult.getResultContents();
 			int length = rawText.size();
diff --git a/src/com/gitblit/utils/FileUtils.java b/src/com/gitblit/utils/FileUtils.java
index 3cfe689..468b2a8 100644
--- a/src/com/gitblit/utils/FileUtils.java
+++ b/src/com/gitblit/utils/FileUtils.java
@@ -34,7 +34,7 @@
 	 * 
 	 * @param file
 	 * @param lineEnding
-	 * @return
+	 * @return the string content of the file
 	 */
 	public static String readContent(File file, String lineEnding) {
 		StringBuilder sb = new StringBuilder();
diff --git a/src/com/gitblit/utils/GitBlitDiffFormatter.java b/src/com/gitblit/utils/GitBlitDiffFormatter.java
index 1441361..0e393fe 100644
--- a/src/com/gitblit/utils/GitBlitDiffFormatter.java
+++ b/src/com/gitblit/utils/GitBlitDiffFormatter.java
@@ -21,6 +21,12 @@
 
 import org.eclipse.jgit.diff.RawText;
 
+/**
+ * Generates an html snippet of a diff in Gitblit's style.
+ * 
+ * @author James Moger
+ * 
+ */
 public class GitBlitDiffFormatter extends GitWebDiffFormatter {
 
 	private final OutputStream os;
diff --git a/src/com/gitblit/utils/GitWebDiffFormatter.java b/src/com/gitblit/utils/GitWebDiffFormatter.java
index b998259..00ea121 100644
--- a/src/com/gitblit/utils/GitWebDiffFormatter.java
+++ b/src/com/gitblit/utils/GitWebDiffFormatter.java
@@ -24,6 +24,12 @@
 import org.eclipse.jgit.diff.DiffFormatter;
 import org.eclipse.jgit.diff.RawText;
 
+/**
+ * Returns an html snippet of the diff in the standard Gitweb style.
+ * 
+ * @author James Moger
+ * 
+ */
 public class GitWebDiffFormatter extends DiffFormatter {
 
 	private final OutputStream os;
diff --git a/src/com/gitblit/utils/MarkdownUtils.java b/src/com/gitblit/utils/MarkdownUtils.java
index 697fa99..c7c1f9f 100644
--- a/src/com/gitblit/utils/MarkdownUtils.java
+++ b/src/com/gitblit/utils/MarkdownUtils.java
@@ -23,8 +23,21 @@
 import org.tautua.markdownpapers.Markdown;
 import org.tautua.markdownpapers.parser.ParseException;
 
+/**
+ * Utility methods for transforming raw markdown text to html.
+ * 
+ * @author James Moger
+ * 
+ */
 public class MarkdownUtils {
 
+	/**
+	 * Returns the html version of the markdown source text.
+	 * 
+	 * @param markdown
+	 * @return html version of markdown text
+	 * @throws java.text.ParseException
+	 */
 	public static String transformMarkdown(String markdown) throws java.text.ParseException {
 		try {
 			return transformMarkdown(new StringReader(markdown));
@@ -33,6 +46,14 @@
 		}
 	}
 
+	/**
+	 * Returns the html version of the markdown source reader. The reader is
+	 * closed regardless of success or failure.
+	 * 
+	 * @param markdownReader
+	 * @return html version of the markdown text
+	 * @throws java.text.ParseException
+	 */
 	public static String transformMarkdown(Reader markdownReader) throws java.text.ParseException {
 		// Read raw markdown content and transform it to html
 		StringWriter writer = new StringWriter();
diff --git a/src/com/gitblit/utils/MetricUtils.java b/src/com/gitblit/utils/MetricUtils.java
index 85ef89f..acdacc4 100644
--- a/src/com/gitblit/utils/MetricUtils.java
+++ b/src/com/gitblit/utils/MetricUtils.java
@@ -35,33 +35,58 @@
 import com.gitblit.models.Metric;
 import com.gitblit.models.RefModel;
 
+/**
+ * Utility class for collecting metrics on a branch, tag, or other ref within
+ * the repository.
+ * 
+ * @author James Moger
+ * 
+ */
 public class MetricUtils {
 
 	private static final Logger LOGGER = LoggerFactory.getLogger(MetricUtils.class);
 
-	public static List<Metric> getDateMetrics(Repository r, String objectId, boolean includeTotal,
-			String format) {
+	/**
+	 * Returns the list of metrics for the specified commit reference, branch,
+	 * or tag within the repository. If includeTotal is true, the total of all
+	 * the metrics will be included as the first element in the returned list.
+	 * 
+	 * If the dateformat is unspecified an attempt is made to determine an
+	 * appropriate date format by determining the time difference between the
+	 * first commit on the branch and the most recent commit. This assumes that
+	 * the commits are linear.
+	 * 
+	 * @param repository
+	 * @param objectId
+	 *            if null or empty, HEAD is assumed.
+	 * @param includeTotal
+	 * @param dateFormat
+	 * @return list of metrics
+	 */
+	public static List<Metric> getDateMetrics(Repository repository, String objectId,
+			boolean includeTotal, String dateFormat) {
 		Metric total = new Metric("TOTAL");
 		final Map<String, Metric> metricMap = new HashMap<String, Metric>();
 		if (StringUtils.isEmpty(objectId)) {
 			objectId = Constants.HEAD;
 		}
-		if (JGitUtils.hasCommits(r)) {
-			final List<RefModel> tags = JGitUtils.getTags(r, true, -1);
+		if (JGitUtils.hasCommits(repository)) {
+			final List<RefModel> tags = JGitUtils.getTags(repository, true, -1);
 			final Map<ObjectId, RefModel> tagMap = new HashMap<ObjectId, RefModel>();
 			for (RefModel tag : tags) {
 				tagMap.put(tag.getReferencedObjectId(), tag);
 			}
+			RevWalk revWalk = null;
 			try {
-				RevWalk walk = new RevWalk(r);
-				ObjectId object = r.resolve(objectId);
-				RevCommit lastCommit = walk.parseCommit(object);
-				walk.markStart(lastCommit);
+				revWalk = new RevWalk(repository);
+				ObjectId object = repository.resolve(objectId);
+				RevCommit lastCommit = revWalk.parseCommit(object);
+				revWalk.markStart(lastCommit);
 
 				DateFormat df;
-				if (StringUtils.isEmpty(format)) {
+				if (StringUtils.isEmpty(dateFormat)) {
 					// dynamically determine date format
-					RevCommit firstCommit = JGitUtils.getFirstCommit(r, Constants.HEAD);
+					RevCommit firstCommit = JGitUtils.getFirstCommit(repository, Constants.HEAD);
 					int diffDays = (lastCommit.getCommitTime() - firstCommit.getCommitTime())
 							/ (60 * 60 * 24);
 					total.duration = diffDays;
@@ -74,10 +99,10 @@
 					}
 				} else {
 					// use specified date format
-					df = new SimpleDateFormat(format);
+					df = new SimpleDateFormat(dateFormat);
 				}
 
-				Iterable<RevCommit> revlog = walk;
+				Iterable<RevCommit> revlog = revWalk;
 				for (RevCommit rev : revlog) {
 					Date d = JGitUtils.getCommitDate(rev);
 					String p = df.format(d);
@@ -94,6 +119,10 @@
 				}
 			} catch (Throwable t) {
 				LOGGER.error("Failed to mine log history for date metrics", t);
+			} finally {
+				if (revWalk != null) {
+					revWalk.dispose();
+				}
 			}
 		}
 		List<String> keys = new ArrayList<String>(metricMap.keySet());
@@ -108,22 +137,33 @@
 		return metrics;
 	}
 
-	public static List<Metric> getAuthorMetrics(Repository r, String objectId, boolean byEmail) {
+	/**
+	 * Returns a list of author metrics for the specified repository.
+	 * 
+	 * @param repository
+	 * @param objectId
+	 *            if null or empty, HEAD is assumed.
+	 * @param byEmailAddress
+	 *            group metrics by author email address otherwise by author name
+	 * @return list of metrics
+	 */
+	public static List<Metric> getAuthorMetrics(Repository repository, String objectId,
+			boolean byEmailAddress) {
 		final Map<String, Metric> metricMap = new HashMap<String, Metric>();
 		if (StringUtils.isEmpty(objectId)) {
 			objectId = Constants.HEAD;
 		}
-		if (JGitUtils.hasCommits(r)) {
+		if (JGitUtils.hasCommits(repository)) {
 			try {
-				RevWalk walk = new RevWalk(r);
-				ObjectId object = r.resolve(objectId);
+				RevWalk walk = new RevWalk(repository);
+				ObjectId object = repository.resolve(objectId);
 				RevCommit lastCommit = walk.parseCommit(object);
 				walk.markStart(lastCommit);
 
 				Iterable<RevCommit> revlog = walk;
 				for (RevCommit rev : revlog) {
 					String p;
-					if (byEmail) {
+					if (byEmailAddress) {
 						p = rev.getAuthorIdent().getEmailAddress().toLowerCase();
 						if (StringUtils.isEmpty(p)) {
 							p = rev.getAuthorIdent().getName().toLowerCase();
diff --git a/src/com/gitblit/utils/PatchFormatter.java b/src/com/gitblit/utils/PatchFormatter.java
index daa15aa..9255956 100644
--- a/src/com/gitblit/utils/PatchFormatter.java
+++ b/src/com/gitblit/utils/PatchFormatter.java
@@ -30,6 +30,12 @@
 
 import com.gitblit.Constants;
 
+/**
+ * A diff formatter that outputs standard patch content.
+ * 
+ * @author James Moger
+ * 
+ */
 public class PatchFormatter extends DiffFormatter {
 
 	private final OutputStream os;
diff --git a/src/com/gitblit/utils/StringUtils.java b/src/com/gitblit/utils/StringUtils.java
index 219699f..bb1928a 100644
--- a/src/com/gitblit/utils/StringUtils.java
+++ b/src/com/gitblit/utils/StringUtils.java
@@ -22,18 +22,44 @@
 import java.util.List;
 import java.util.regex.PatternSyntaxException;
 
+/**
+ * Utility class of string functions.
+ * 
+ * @author James Moger
+ * 
+ */
 public class StringUtils {
 
 	public static final String MD5_TYPE = "MD5:";
 
+	/**
+	 * Returns true if the string is null or empty.
+	 * 
+	 * @param value
+	 * @return true if string is null or empty
+	 */
 	public static boolean isEmpty(String value) {
 		return value == null || value.trim().length() == 0;
 	}
 
+	/**
+	 * Replaces carriage returns and line feeds with html line breaks.
+	 * 
+	 * @param string
+	 * @return plain text with html line breaks
+	 */
 	public static String breakLinesForHtml(String string) {
 		return string.replace("\r\n", "<br/>").replace("\r", "<br/>").replace("\n", "<br/>");
 	}
 
+	/**
+	 * Prepare text for html presentation. Replace sensitive characters with
+	 * html entities.
+	 * 
+	 * @param inStr
+	 * @param changeSpace
+	 * @return plain text escaped for html
+	 */
 	public static String escapeForHtml(String inStr, boolean changeSpace) {
 		StringBuffer retStr = new StringBuffer();
 		int i = 0;
@@ -58,11 +84,23 @@
 		return retStr.toString();
 	}
 
+	/**
+	 * Decode html entities back into plain text characters.
+	 * 
+	 * @param inStr
+	 * @return returns plain text from html
+	 */
 	public static String decodeFromHtml(String inStr) {
 		return inStr.replace("&amp;", "&").replace("&lt;", "<").replace("&gt;", ">")
 				.replace("&quot;", "\"").replace("&nbsp;", " ");
 	}
 
+	/**
+	 * Encodes a url parameter by escaping troublesome characters.
+	 * 
+	 * @param inStr
+	 * @return properly escaped url
+	 */
 	public static String encodeURL(String inStr) {
 		StringBuffer retStr = new StringBuffer();
 		int i = 0;
@@ -79,10 +117,24 @@
 		return retStr.toString();
 	}
 
+	/**
+	 * Flatten the list of strings into a single string with a space separator.
+	 * 
+	 * @param values
+	 * @return flattened list
+	 */
 	public static String flattenStrings(List<String> values) {
 		return flattenStrings(values, " ");
 	}
 
+	/**
+	 * Flatten the list of strings into a single string with the specified
+	 * separator.
+	 * 
+	 * @param values
+	 * @param separator
+	 * @return flattened list
+	 */
 	public static String flattenStrings(List<String> values, String separator) {
 		StringBuilder sb = new StringBuilder();
 		for (String value : values) {
@@ -91,6 +143,15 @@
 		return sb.toString().trim();
 	}
 
+	/**
+	 * Returns a string trimmed to a maximum length with trailing ellipses. If
+	 * the string length is shorter than the max, the original string is
+	 * returned.
+	 * 
+	 * @param value
+	 * @param max
+	 * @return trimmed string
+	 */
 	public static String trimString(String value, int max) {
 		if (value.length() <= max) {
 			return value;
@@ -98,10 +159,25 @@
 		return value.substring(0, max - 3) + "...";
 	}
 
+	/**
+	 * Returns a trimmed shortlog message.
+	 * 
+	 * @param string
+	 * @return trimmed shortlog message
+	 */
 	public static String trimShortLog(String string) {
 		return trimString(string, 60);
 	}
 
+	/**
+	 * Left pad a string with the specified character, if the string length is
+	 * less than the specified length.
+	 * 
+	 * @param input
+	 * @param length
+	 * @param pad
+	 * @return left-padded string
+	 */
 	public static String leftPad(String input, int length, char pad) {
 		if (input.length() < length) {
 			StringBuilder sb = new StringBuilder();
@@ -114,6 +190,15 @@
 		return input;
 	}
 
+	/**
+	 * Right pad a string with the specified character, if the string length is
+	 * less then the specified length.
+	 * 
+	 * @param input
+	 * @param length
+	 * @param pad
+	 * @return right-padded string
+	 */
 	public static String rightPad(String input, int length, char pad) {
 		if (input.length() < length) {
 			StringBuilder sb = new StringBuilder();
@@ -126,6 +211,12 @@
 		return input;
 	}
 
+	/**
+	 * Calculates the SHA1 of the string.
+	 * 
+	 * @param text
+	 * @return sha1 of the string
+	 */
 	public static String getSHA1(String text) {
 		try {
 			byte[] bytes = text.getBytes("iso-8859-1");
@@ -135,6 +226,12 @@
 		}
 	}
 
+	/**
+	 * Calculates the SHA1 of the byte array.
+	 * 
+	 * @param bytes
+	 * @return sha1 of the byte array
+	 */
 	public static String getSHA1(byte[] bytes) {
 		try {
 			MessageDigest md = MessageDigest.getInstance("SHA-1");
@@ -146,6 +243,12 @@
 		}
 	}
 
+	/**
+	 * Calculates the MD5 of the string.
+	 * 
+	 * @param string
+	 * @return md5 of the string
+	 */
 	public static String getMD5(String string) {
 		try {
 			MessageDigest md = MessageDigest.getInstance("MD5");
@@ -160,6 +263,12 @@
 		}
 	}
 
+	/**
+	 * Returns the hex representation of the byte array.
+	 * 
+	 * @param bytes
+	 * @return byte array as hex string
+	 */
 	private static String toHex(byte[] bytes) {
 		StringBuilder sb = new StringBuilder(bytes.length * 2);
 		for (int i = 0; i < bytes.length; i++) {
@@ -171,6 +280,13 @@
 		return sb.toString();
 	}
 
+	/**
+	 * Returns the root path of the specified path. Returns a blank string if
+	 * there is no root path.
+	 * 
+	 * @param path
+	 * @return root path or blank
+	 */
 	public static String getRootPath(String path) {
 		if (path.indexOf('/') > -1) {
 			return path.substring(0, path.lastIndexOf('/'));
@@ -178,6 +294,14 @@
 		return "";
 	}
 
+	/**
+	 * Returns the path remainder after subtracting the basePath from the
+	 * fullPath.
+	 * 
+	 * @param basePath
+	 * @param fullPath
+	 * @return the relative path
+	 */
 	public static String getRelativePath(String basePath, String fullPath) {
 		String relativePath = fullPath.substring(basePath.length()).replace('\\', '/');
 		if (relativePath.charAt(0) == '/') {
@@ -186,10 +310,23 @@
 		return relativePath;
 	}
 
+	/**
+	 * Splits the space-separated string into a list of strings.
+	 * 
+	 * @param value
+	 * @return list of strings
+	 */
 	public static List<String> getStringsFromValue(String value) {
 		return getStringsFromValue(value, " ");
 	}
 
+	/**
+	 * Splits the string into a list of string by the specified separator.
+	 * 
+	 * @param value
+	 * @param separator
+	 * @return list of strings
+	 */
 	public static List<String> getStringsFromValue(String value, String separator) {
 		List<String> strings = new ArrayList<String>();
 		try {
diff --git a/src/com/gitblit/utils/SyndicationUtils.java b/src/com/gitblit/utils/SyndicationUtils.java
index 80a1b28..fb40dd5 100644
--- a/src/com/gitblit/utils/SyndicationUtils.java
+++ b/src/com/gitblit/utils/SyndicationUtils.java
@@ -35,8 +35,26 @@
 import com.sun.syndication.io.FeedException;
 import com.sun.syndication.io.SyndFeedOutput;
 
+/**
+ * Utility class for RSS feeds.
+ * 
+ * @author James Moger
+ * 
+ */
 public class SyndicationUtils {
 
+	/**
+	 * Outputs an RSS feed of the list of commits to the outputstream.
+	 * 
+	 * @param hostUrl
+	 * @param title
+	 * @param description
+	 * @param repository
+	 * @param commits
+	 * @param os
+	 * @throws IOException
+	 * @throws FeedException
+	 */
 	public static void toRSS(String hostUrl, String title, String description, String repository,
 			List<RevCommit> commits, OutputStream os) throws IOException, FeedException {
 
diff --git a/src/com/gitblit/utils/TicgitUtils.java b/src/com/gitblit/utils/TicgitUtils.java
index 48e8558..87a2b3a 100644
--- a/src/com/gitblit/utils/TicgitUtils.java
+++ b/src/com/gitblit/utils/TicgitUtils.java
@@ -30,15 +30,28 @@
 import com.gitblit.models.TicketModel;
 import com.gitblit.models.TicketModel.Comment;
 
+/**
+ * Utility class for reading Ticgit issues.
+ * 
+ * @author James Moger
+ * 
+ */
 public class TicgitUtils {
 
 	static final Logger LOGGER = LoggerFactory.getLogger(TicgitUtils.class);
 
-	public static RefModel getTicketsBranch(Repository r) {
+	/**
+	 * Returns a RefModel for the Ticgit branch in the repository. If the branch
+	 * can not be found, null is returned.
+	 * 
+	 * @param repository
+	 * @return a refmodel for the ticgit branch or null
+	 */
+	public static RefModel getTicketsBranch(Repository repository) {
 		RefModel ticgitBranch = null;
 		try {
 			// search for ticgit branch in local heads
-			for (RefModel ref : JGitUtils.getLocalBranches(r, false, -1)) {
+			for (RefModel ref : JGitUtils.getLocalBranches(repository, false, -1)) {
 				if (ref.displayName.endsWith("ticgit")) {
 					ticgitBranch = ref;
 					break;
@@ -47,7 +60,7 @@
 
 			// search for ticgit branch in remote heads
 			if (ticgitBranch == null) {
-				for (RefModel ref : JGitUtils.getRemoteBranches(r, false, -1)) {
+				for (RefModel ref : JGitUtils.getRemoteBranches(repository, false, -1)) {
 					if (ref.displayName.endsWith("ticgit")) {
 						ticgitBranch = ref;
 						break;
@@ -60,19 +73,25 @@
 		return ticgitBranch;
 	}
 
-	public static List<TicketModel> getTickets(Repository r) {
-		RefModel ticgitBranch = getTicketsBranch(r);
+	/**
+	 * Returns a list of all tickets in the ticgit branch of the repository.
+	 * 
+	 * @param repository
+	 * @return list of tickets
+	 */
+	public static List<TicketModel> getTickets(Repository repository) {
+		RefModel ticgitBranch = getTicketsBranch(repository);
 		if (ticgitBranch == null) {
 			return null;
 		}
 		RevCommit commit = (RevCommit) ticgitBranch.referencedObject;
-		List<PathModel> paths = JGitUtils.getFilesInPath(r, null, commit);
+		List<PathModel> paths = JGitUtils.getFilesInPath(repository, null, commit);
 		List<TicketModel> tickets = new ArrayList<TicketModel>();
 		for (PathModel ticketFolder : paths) {
 			if (ticketFolder.isTree()) {
 				try {
 					TicketModel t = new TicketModel(ticketFolder.name);
-					readTicketContents(r, ticgitBranch, t);
+					loadTicketContents(repository, ticgitBranch, t);
 					tickets.add(t);
 				} catch (Throwable t) {
 					LOGGER.error("Failed to get a ticket!", t);
@@ -84,12 +103,20 @@
 		return tickets;
 	}
 
-	public static TicketModel getTicket(Repository r, String ticketFolder) {
-		RefModel ticketsBranch = getTicketsBranch(r);
+	/**
+	 * Returns a TicketModel for the specified ticgit ticket. Returns null if
+	 * the ticket does not exist or some other error occurs.
+	 * 
+	 * @param repository
+	 * @param ticketFolder
+	 * @return a ticket
+	 */
+	public static TicketModel getTicket(Repository repository, String ticketFolder) {
+		RefModel ticketsBranch = getTicketsBranch(repository);
 		if (ticketsBranch != null) {
 			try {
 				TicketModel ticket = new TicketModel(ticketFolder);
-				readTicketContents(r, ticketsBranch, ticket);
+				loadTicketContents(repository, ticketsBranch, ticket);
 				return ticket;
 			} catch (Throwable t) {
 				LOGGER.error("Failed to get ticket " + ticketFolder, t);
@@ -98,11 +125,20 @@
 		return null;
 	}
 
-	private static void readTicketContents(Repository r, RefModel ticketsBranch, TicketModel ticket) {
+	/**
+	 * Loads the contents of the ticket.
+	 * 
+	 * @param repository
+	 * @param ticketsBranch
+	 * @param ticket
+	 */
+	private static void loadTicketContents(Repository repository, RefModel ticketsBranch,
+			TicketModel ticket) {
 		RevCommit commit = (RevCommit) ticketsBranch.referencedObject;
-		List<PathModel> ticketFiles = JGitUtils.getFilesInPath(r, ticket.name, commit);
+		List<PathModel> ticketFiles = JGitUtils.getFilesInPath(repository, ticket.name, commit);
 		for (PathModel file : ticketFiles) {
-			String content = JGitUtils.getStringContent(r, commit.getTree(), file.path).trim();
+			String content = JGitUtils.getStringContent(repository, commit.getTree(), file.path)
+					.trim();
 			if (file.name.equals("TICKET_ID")) {
 				ticket.id = content;
 			} else if (file.name.equals("TITLE")) {
diff --git a/src/com/gitblit/utils/TimeUtils.java b/src/com/gitblit/utils/TimeUtils.java
index dcb60ab..ad81463 100644
--- a/src/com/gitblit/utils/TimeUtils.java
+++ b/src/com/gitblit/utils/TimeUtils.java
@@ -18,6 +18,12 @@
 import java.util.Calendar;
 import java.util.Date;
 
+/**
+ * Utility class of time functions.
+ * 
+ * @author James Moger
+ * 
+ */
 public class TimeUtils {
 	public static final long MIN = 1000 * 60L;
 
@@ -29,10 +35,22 @@
 
 	public static final long ONEYEAR = ONEDAY * 365L;
 
+	/**
+	 * Returns true if date is today.
+	 * 
+	 * @param date
+	 * @return true if date is today
+	 */
 	public static boolean isToday(Date date) {
 		return (System.currentTimeMillis() - date.getTime()) < ONEDAY;
 	}
 
+	/**
+	 * Returns true if date is yesterday.
+	 * 
+	 * @param date
+	 * @return true if date is yesterday
+	 */
 	public static boolean isYesterday(Date date) {
 		Calendar cal = Calendar.getInstance();
 		cal.setTime(date);
@@ -40,6 +58,13 @@
 		return (System.currentTimeMillis() - cal.getTimeInMillis()) < ONEDAY;
 	}
 
+	/**
+	 * Returns the string representation of the duration as days, months and/or
+	 * years.
+	 * 
+	 * @param days
+	 * @return duration as string in days, months, and/or years
+	 */
 	public static String duration(int days) {
 		if (days <= 60) {
 			return days + (days > 1 ? " days" : " day");
@@ -69,6 +94,15 @@
 		}
 	}
 
+	/**
+	 * Returns the number of minutes ago between the start time and the end
+	 * time.
+	 * 
+	 * @param date
+	 * @param endTime
+	 * @param roundup
+	 * @return difference in minutes
+	 */
 	public static int minutesAgo(Date date, long endTime, boolean roundup) {
 		long diff = endTime - date.getTime();
 		int mins = (int) (diff / MIN);
@@ -78,10 +112,24 @@
 		return mins;
 	}
 
+	/**
+	 * Return the difference in minutes between now and the date.
+	 * 
+	 * @param date
+	 * @param roundup
+	 * @return minutes ago
+	 */
 	public static int minutesAgo(Date date, boolean roundup) {
 		return minutesAgo(date, System.currentTimeMillis(), roundup);
 	}
 
+	/**
+	 * Return the difference in hours between now and the date.
+	 * 
+	 * @param date
+	 * @param roundup
+	 * @return hours ago
+	 */
 	public static int hoursAgo(Date date, boolean roundup) {
 		long diff = System.currentTimeMillis() - date.getTime();
 		int hours = (int) (diff / ONEHOUR);
@@ -91,6 +139,13 @@
 		return hours;
 	}
 
+	/**
+	 * Return the difference in days between now and the date.
+	 * 
+	 * @param date
+	 * @param roundup
+	 * @return days ago
+	 */
 	public static int daysAgo(Date date, boolean roundup) {
 		long diff = System.currentTimeMillis() - date.getTime();
 		int days = (int) (diff / ONEDAY);
@@ -100,14 +155,35 @@
 		return days;
 	}
 
+	/**
+	 * Returns the string representation of the duration between now and the
+	 * date.
+	 * 
+	 * @param date
+	 * @return duration as a string
+	 */
 	public static String timeAgo(Date date) {
 		return timeAgo(date, false);
 	}
 
+	/**
+	 * Returns the CSS class for the date based on its age from Now.
+	 * 
+	 * @param date
+	 * @return the css class
+	 */
 	public static String timeAgoCss(Date date) {
 		return timeAgo(date, true);
 	}
 
+	/**
+	 * Returns the string representation of the duration OR the css class for
+	 * the duration.
+	 * 
+	 * @param date
+	 * @param css
+	 * @return the string representation of the duration OR the css class
+	 */
 	private static String timeAgo(Date date, boolean css) {
 		String ago = null;
 		if (isToday(date) || isYesterday(date)) {

--
Gitblit v1.9.1