Factor out common walking logic in PathServlet

We can't just use a TreeWalk for this in all cases because it has no
concept of being positioned just before a root tree. Plus, there are
various other pieces that we pass around with TreeWalk that make sense
to encapsulate together.

Change-Id: Ia82d4df558aceef4c2ddd8a0b17972fbd3db01e0
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/BlobSoyData.java b/gitiles-servlet/src/main/java/com/google/gitiles/BlobSoyData.java
index 02cb54c..857fa91 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/BlobSoyData.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/BlobSoyData.java
@@ -29,6 +29,7 @@
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.ObjectLoader;
+import org.eclipse.jgit.lib.ObjectReader;
 import org.eclipse.jgit.revwalk.RevWalk;
 import org.eclipse.jgit.util.RawParseUtils;
 import org.slf4j.Logger;
@@ -55,11 +56,16 @@
   private static final int MAX_FILE_SIZE = 10 << 20;
 
   private final GitilesView view;
-  private final RevWalk walk;
+  private final ObjectReader reader;
 
+  // TODO(dborowitz): Remove this constructor.
   public BlobSoyData(RevWalk walk, GitilesView view) {
+    this(walk.getObjectReader(), view);
+  }
+
+  public BlobSoyData(ObjectReader reader, GitilesView view) {
+    this.reader = reader;
     this.view = view;
-    this.walk = walk;
   }
 
   public Map<String, Object> toSoyData(ObjectId blobId)
@@ -72,7 +78,7 @@
     Map<String, Object> data = Maps.newHashMapWithExpectedSize(4);
     data.put("sha", ObjectId.toString(blobId));
 
-    ObjectLoader loader = walk.getObjectReader().open(blobId, Constants.OBJ_BLOB);
+    ObjectLoader loader = reader.open(blobId, Constants.OBJ_BLOB);
     String content;
     try {
       byte[] raw = loader.getCachedBytes(MAX_FILE_SIZE);