Added functionality to show notes

Feature: Issue 45
Change-Id: Idf290212e5447987330a2741bfe57e297c50a93a
diff --git a/java/com/google/gitiles/CommitData.java b/java/com/google/gitiles/CommitData.java
index 705240e..23f03e8 100644
--- a/java/com/google/gitiles/CommitData.java
+++ b/java/com/google/gitiles/CommitData.java
@@ -41,6 +41,7 @@
 import org.eclipse.jgit.lib.PersonIdent;
 import org.eclipse.jgit.lib.Ref;
 import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.notes.NoteMap;
 import org.eclipse.jgit.revwalk.RevCommit;
 import org.eclipse.jgit.revwalk.RevWalk;
 import org.eclipse.jgit.treewalk.AbstractTreeIterator;
@@ -60,6 +61,7 @@
     DIFF_TREE,
     LOG_URL,
     MESSAGE,
+    NOTES,
     PARENTS,
     PARENT_BLAME_URL,
     SHA,
@@ -83,6 +85,7 @@
   static class Builder {
     private ArchiveFormat archiveFormat;
     private Map<AnyObjectId, Set<Ref>> refsById;
+    private static final int MAX_NOTE_SIZE = 524288;
 
     Builder setArchiveFormat(@Nullable ArchiveFormat archiveFormat) {
       this.archiveFormat = archiveFormat;
@@ -145,6 +148,19 @@
       if (fs.contains(Field.TAGS)) {
         result.tags = getRefsById(repo, c, Constants.R_TAGS);
       }
+      if (fs.contains(Field.NOTES)) {
+        Ref notesRef = repo.getRefDatabase().exactRef(Constants.R_NOTES_COMMITS);
+        if (notesRef != null) {
+          try {
+            byte[] data =
+                NoteMap.read(walk.getObjectReader(), walk.parseCommit(notesRef.getObjectId()))
+                    .getCachedBytes(c, MAX_NOTE_SIZE);
+            result.notes = new String(data, "utf-8");
+          } catch (Exception e) {
+            result.notes = "";
+          }
+        }
+      }
       if (fs.contains(Field.MESSAGE)) {
         walk.parseBody(c);
         result.message = c.getFullMessage();
@@ -167,7 +183,6 @@
       if (fs.contains(Field.DIFF_TREE)) {
         result.diffEntries = computeDiffEntries(repo, view, walk, c);
       }
-
       return result;
     }
 
@@ -251,6 +266,7 @@
   List<RevCommit> parents;
   String shortMessage;
   String message;
+  String notes;
 
   List<Ref> branches;
   List<Ref> tags;
diff --git a/java/com/google/gitiles/CommitJsonData.java b/java/com/google/gitiles/CommitJsonData.java
index 953c19c..5f94a70 100644
--- a/java/com/google/gitiles/CommitJsonData.java
+++ b/java/com/google/gitiles/CommitJsonData.java
@@ -32,7 +32,13 @@
 public class CommitJsonData {
   static final ImmutableSet<Field> DEFAULT_FIELDS =
       Sets.immutableEnumSet(
-          Field.SHA, Field.TREE, Field.PARENTS, Field.AUTHOR, Field.COMMITTER, Field.MESSAGE);
+          Field.SHA,
+          Field.TREE,
+          Field.PARENTS,
+          Field.AUTHOR,
+          Field.COMMITTER,
+          Field.MESSAGE,
+          Field.NOTES);
 
   public static class Log {
     public List<Commit> log;
@@ -53,6 +59,7 @@
     Ident author;
     Ident committer;
     String message;
+    String notes;
 
     List<Diff> treeDiff;
   }
@@ -101,6 +108,9 @@
     if (cd.message != null) {
       result.message = cd.message;
     }
+    if (cd.notes != null && !cd.notes.isEmpty()){
+      result.notes = cd.notes;
+    }
     if (cd.diffEntries != null) {
       result.treeDiff = toJsonData(cd.diffEntries);
     }
diff --git a/java/com/google/gitiles/CommitSoyData.java b/java/com/google/gitiles/CommitSoyData.java
index c4087a6..ac81f80 100644
--- a/java/com/google/gitiles/CommitSoyData.java
+++ b/java/com/google/gitiles/CommitSoyData.java
@@ -53,6 +53,7 @@
           Field.TREE_URL,
           Field.PARENTS,
           Field.MESSAGE,
+          Field.NOTES, // Optional Field
           Field.LOG_URL,
           Field.ARCHIVE_URL,
           Field.ARCHIVE_TYPE);
@@ -137,11 +138,20 @@
     if (cd.diffEntries != null) {
       data.put("diffTree", toSoyData(view, cd.diffEntries));
     }
-    checkState(
-        Sets.difference(fs, NESTED_FIELDS).size() == data.size(),
-        "bad commit data fields: %s != %s",
-        fs,
-        data.keySet());
+
+    int diffSetSize = Sets.difference(fs, NESTED_FIELDS).size();
+
+    if (fs.contains(
+        Field.NOTES)) { // Since NOTES is optional this is required for checkState to pass
+      diffSetSize -= 1;
+    }
+
+    checkState(diffSetSize == data.size(), "bad commit data fields: %s != %s", fs, data.keySet());
+
+    if (cd.notes != null && !cd.notes.isEmpty()) {
+      data.put("notes", cd.notes);
+    }
+
     return data;
   }
 
diff --git a/resources/com/google/gitiles/templates/ObjectDetail.soy b/resources/com/google/gitiles/templates/ObjectDetail.soy
index f755720..ac1a1b4 100644
--- a/resources/com/google/gitiles/templates/ObjectDetail.soy
+++ b/resources/com/google/gitiles/templates/ObjectDetail.soy
@@ -32,6 +32,7 @@
       text: raw text of the part.
       url: optional URL that should be linked to from the part.
       */
+  {@param notes: ?} /** the notes for the corresponding commit */
   {@param diffTree: ?}  /** list of changed tree entries with the following keys:
       changeType: string matching an org.eclipse.jgit.diff.DiffEntry.ChangeType constant.
       path: (new) path of the tree entry.
@@ -91,6 +92,15 @@
   {param message: $message /}
 {/call}
 
+{if $notes}
+  <h4>Notes:</h4>
+  <div class="MetadataMessage">
+      <span>
+        {msg desc="Text for the git notes"}{$notes}{/msg}
+      </span>
+  </div>
+{/if}
+
 {if $diffTree and length($diffTree)}
   <ul class="DiffTree">
     {for $entry in $diffTree}