Cache GitilesAccess in the request from BaseServlet

This will allow BaseServlet methods to reuse the same AccessFactory
as subclasses.

Change-Id: I9b160e6943591910b433fc02b382fb4412416380
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/ArchiveServlet.java b/gitiles-servlet/src/main/java/com/google/gitiles/ArchiveServlet.java
index 1fd5009..dc761b0 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/ArchiveServlet.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/ArchiveServlet.java
@@ -14,7 +14,6 @@
 
 package com.google.gitiles;
 
-import static com.google.common.base.Preconditions.checkNotNull;
 import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
 import static javax.servlet.http.HttpServletResponse.SC_OK;
 
@@ -40,11 +39,8 @@
 public class ArchiveServlet extends BaseServlet {
   private static final long serialVersionUID = 1L;
 
-  private final GitilesAccess.Factory accessFactory;
-
   public ArchiveServlet(GitilesAccess.Factory accessFactory) {
-    super(null);
-    this.accessFactory = checkNotNull(accessFactory, "accessFactory");
+    super(null, accessFactory);
   }
 
   @Override
@@ -61,7 +57,7 @@
     }
 
     Optional<ArchiveFormat> format = ArchiveFormat.byExtension(
-        view.getExtension(), accessFactory.forRequest(req).getConfig());
+        view.getExtension(), getAccess(req).getConfig());
     if (!format.isPresent()) {
       res.setStatus(SC_NOT_FOUND);
       return;
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/BaseServlet.java b/gitiles-servlet/src/main/java/com/google/gitiles/BaseServlet.java
index 3c42386..ba0ee5c 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/BaseServlet.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/BaseServlet.java
@@ -45,6 +45,7 @@
 public abstract class BaseServlet extends HttpServlet {
   private static final long serialVersionUID = 1L;
   private static final String DATA_ATTRIBUTE = BaseServlet.class.getName() + "/Data";
+  private static final String ACCESS_ATTRIBUTE = BaseServlet.class.getName() + "/GitilesAccess";
 
   static void setNotCacheable(HttpServletResponse res) {
     res.setHeader(HttpHeaders.CACHE_CONTROL, "no-cache, no-store, max-age=0, must-revalidate");
@@ -54,7 +55,7 @@
   }
 
   public static BaseServlet notFoundServlet() {
-    return new BaseServlet(null) {
+    return new BaseServlet(null, null) {
       private static final long serialVersionUID = 1L;
       @Override
       public void service(HttpServletRequest req, HttpServletResponse res) {
@@ -168,9 +169,11 @@
   }
 
   protected final Renderer renderer;
+  private final GitilesAccess.Factory accessFactory;
 
-  protected BaseServlet(Renderer renderer) {
+  protected BaseServlet(Renderer renderer, GitilesAccess.Factory accessFactory) {
     this.renderer = renderer;
+    this.accessFactory = accessFactory;
   }
 
   /**
@@ -272,6 +275,15 @@
     out.close();
   }
 
+  protected GitilesAccess getAccess(HttpServletRequest req) {
+    GitilesAccess access = (GitilesAccess) req.getAttribute(ACCESS_ATTRIBUTE);
+    if (access == null) {
+      access = accessFactory.forRequest(req);
+      req.setAttribute(ACCESS_ATTRIBUTE, access);
+    }
+    return access;
+  }
+
   protected void setCacheHeaders(HttpServletResponse res) {
     setNotCacheable(res);
   }
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/BlameServlet.java b/gitiles-servlet/src/main/java/com/google/gitiles/BlameServlet.java
index 9278747..a18ca16 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/BlameServlet.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/BlameServlet.java
@@ -47,8 +47,8 @@
 
   private final BlameCache cache;
 
-  public BlameServlet(Renderer renderer, BlameCache cache) {
-    super(renderer);
+  public BlameServlet(GitilesAccess.Factory accessFactory, Renderer renderer, BlameCache cache) {
+    super(renderer, accessFactory);
     this.cache = checkNotNull(cache, "cache");
   }
 
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/DescribeServlet.java b/gitiles-servlet/src/main/java/com/google/gitiles/DescribeServlet.java
index 7e9afb6..893089e 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/DescribeServlet.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/DescribeServlet.java
@@ -53,8 +53,8 @@
         && (values.get(0).equals("") || values.get(0).equals("1"));
   }
 
-  protected DescribeServlet() {
-    super(null);
+  protected DescribeServlet(GitilesAccess.Factory accessFactory) {
+    super(null, accessFactory);
   }
 
   @Override
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/DiffServlet.java b/gitiles-servlet/src/main/java/com/google/gitiles/DiffServlet.java
index 04e8391..2a18afb 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/DiffServlet.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/DiffServlet.java
@@ -47,13 +47,11 @@
   private static final long serialVersionUID = 1L;
   private static final String PLACEHOLDER = "id=\"DIFF_OUTPUT_BLOCK\"";
 
-  private final GitilesAccess.Factory accessFactory;
   private final Linkifier linkifier;
 
   public DiffServlet(GitilesAccess.Factory accessFactory, Renderer renderer,
       Linkifier linkifier) {
-    super(renderer);
-    this.accessFactory = checkNotNull(accessFactory, "accessFactory");
+    super(renderer, accessFactory);
     this.linkifier = checkNotNull(linkifier, "linkifier");
   }
 
@@ -87,7 +85,7 @@
         GitDateFormatter df = new GitDateFormatter(Format.DEFAULT);
         data.put("commit", new CommitSoyData()
             .setLinkifier(linkifier)
-            .setArchiveFormat(getArchiveFormat(accessFactory.forRequest(req)))
+            .setArchiveFormat(getArchiveFormat(getAccess(req)))
             .toSoyData(req, walk.parseCommit(view.getRevision().getId()), df));
       }
       if (!data.containsKey("repositoryName") && (view.getRepositoryName() != null)) {
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/GitilesFilter.java b/gitiles-servlet/src/main/java/com/google/gitiles/GitilesFilter.java
index 62164f1..e8b161d 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/GitilesFilter.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/GitilesFilter.java
@@ -230,11 +230,11 @@
     checkNotInitialized();
     switch (view) {
       case HOST_INDEX:
-        return new HostIndexServlet(renderer, urls, accessFactory);
+        return new HostIndexServlet(accessFactory, renderer, urls);
       case REPOSITORY_INDEX:
-        return new RepositoryIndexServlet(renderer, accessFactory, timeCache);
+        return new RepositoryIndexServlet(accessFactory, renderer, timeCache);
       case REFS:
-        return new RefServlet(renderer, timeCache);
+        return new RefServlet(accessFactory, renderer, timeCache);
       case REVISION:
         return new RevisionServlet(accessFactory, renderer, linkifier());
       case PATH:
@@ -242,13 +242,13 @@
       case DIFF:
         return new DiffServlet(accessFactory, renderer, linkifier());
       case LOG:
-        return new LogServlet(renderer, linkifier());
+        return new LogServlet(accessFactory, renderer, linkifier());
       case DESCRIBE:
-        return new DescribeServlet();
+        return new DescribeServlet(accessFactory);
       case ARCHIVE:
         return new ArchiveServlet(accessFactory);
       case BLAME:
-        return new BlameServlet(renderer, blameCache);
+        return new BlameServlet(accessFactory, renderer, blameCache);
       default:
         throw new IllegalArgumentException("Invalid view type: " + view);
     }
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/HostIndexServlet.java b/gitiles-servlet/src/main/java/com/google/gitiles/HostIndexServlet.java
index db563ff..366ed4d 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/HostIndexServlet.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/HostIndexServlet.java
@@ -49,13 +49,11 @@
   private static final Logger log = LoggerFactory.getLogger(HostIndexServlet.class);
 
   protected final GitilesUrls urls;
-  private final GitilesAccess.Factory accessFactory;
 
-  public HostIndexServlet(Renderer renderer, GitilesUrls urls,
-      GitilesAccess.Factory accessFactory) {
-    super(renderer);
+  public HostIndexServlet(GitilesAccess.Factory accessFactory, Renderer renderer,
+      GitilesUrls urls) {
+    super(renderer, accessFactory);
     this.urls = checkNotNull(urls, "urls");
-    this.accessFactory = checkNotNull(accessFactory, "accessFactory");
   }
 
   private Map<String, RepositoryDescription> getDescriptions(HttpServletRequest req,
@@ -67,7 +65,7 @@
       HttpServletResponse res, Set<String> branches) throws IOException {
     Map<String, RepositoryDescription> descs;
     try {
-      descs = accessFactory.forRequest(req).listRepositories(branches);
+      descs = getAccess(req).listRepositories(branches);
     } catch (RepositoryNotFoundException e) {
       res.sendError(SC_NOT_FOUND);
       return null;
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/LogServlet.java b/gitiles-servlet/src/main/java/com/google/gitiles/LogServlet.java
index e6ae4c2..ba979bc 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/LogServlet.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/LogServlet.java
@@ -69,8 +69,8 @@
 
   private final Linkifier linkifier;
 
-  public LogServlet(Renderer renderer, Linkifier linkifier) {
-    super(renderer);
+  public LogServlet(GitilesAccess.Factory accessFactory, Renderer renderer, Linkifier linkifier) {
+    super(renderer, accessFactory);
     this.linkifier = checkNotNull(linkifier, "linkifier");
   }
 
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/PathServlet.java b/gitiles-servlet/src/main/java/com/google/gitiles/PathServlet.java
index dd399ba..d946f2b 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/PathServlet.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/PathServlet.java
@@ -106,12 +106,10 @@
     }
   }
 
-  private final GitilesAccess.Factory accessFactory;
   private final GitilesUrls urls;
 
   public PathServlet(GitilesAccess.Factory accessFactory, Renderer renderer, GitilesUrls urls) {
-    super(renderer);
-    this.accessFactory = checkNotNull(accessFactory, "accessFactory");
+    super(renderer, accessFactory);
     this.urls = checkNotNull(urls, "urls");
   }
 
@@ -341,7 +339,7 @@
         "breadcrumbs", view.getBreadcrumbs(hasSingleTree),
         "type", FileType.TREE.toString(),
         "data", new TreeSoyData(rw, view)
-            .setArchiveFormat(getArchiveFormat(accessFactory.forRequest(req)))
+            .setArchiveFormat(getArchiveFormat(getAccess(req)))
             .toSoyData(id, tw)));
   }
 
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/RefServlet.java b/gitiles-servlet/src/main/java/com/google/gitiles/RefServlet.java
index 8d259a8..4eaf7f3 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/RefServlet.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/RefServlet.java
@@ -49,8 +49,9 @@
 
   private final TimeCache timeCache;
 
-  protected RefServlet(Renderer renderer, TimeCache timeCache) {
-    super(renderer);
+  protected RefServlet(GitilesAccess.Factory accessFactory, Renderer renderer,
+      TimeCache timeCache) {
+    super(renderer, accessFactory);
     this.timeCache = checkNotNull(timeCache, "timeCache");
   }
 
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/RepositoryIndexServlet.java b/gitiles-servlet/src/main/java/com/google/gitiles/RepositoryIndexServlet.java
index ec67621..09d9918 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/RepositoryIndexServlet.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/RepositoryIndexServlet.java
@@ -45,13 +45,11 @@
   static final int REF_LIMIT = 10;
   private static final int LOG_LIMIT = 20;
 
-  private final GitilesAccess.Factory accessFactory;
   private final TimeCache timeCache;
 
-  public RepositoryIndexServlet(Renderer renderer, GitilesAccess.Factory accessFactory,
+  public RepositoryIndexServlet(GitilesAccess.Factory accessFactory, Renderer renderer,
       TimeCache timeCache) {
-    super(renderer);
-    this.accessFactory = checkNotNull(accessFactory, "accessFactory");
+    super(renderer, accessFactory);
     this.timeCache = checkNotNull(timeCache, "timeCache");
   }
 
@@ -64,7 +62,7 @@
   Map<String, ?> buildData(HttpServletRequest req) throws IOException {
     GitilesView view = ViewFilter.getView(req);
     Repository repo = ServletUtils.getRepository(req);
-    RepositoryDescription desc = accessFactory.forRequest(req).getRepositoryDescription();
+    RepositoryDescription desc = getAccess(req).getRepositoryDescription();
     RevWalk walk = new RevWalk(repo);
     List<Map<String, Object>> tags;
     Map<String, Object> data;
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/RevisionServlet.java b/gitiles-servlet/src/main/java/com/google/gitiles/RevisionServlet.java
index 5ac2ad0..113a6f6 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/RevisionServlet.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/RevisionServlet.java
@@ -59,13 +59,11 @@
   private static final long serialVersionUID = 1L;
   private static final Logger log = LoggerFactory.getLogger(RevisionServlet.class);
 
-  private final GitilesAccess.Factory accessFactory;
   private final Linkifier linkifier;
 
   public RevisionServlet(GitilesAccess.Factory accessFactory, Renderer renderer,
       Linkifier linkifier) {
-    super(renderer);
-    this.accessFactory = accessFactory;
+    super(renderer, accessFactory);
     this.linkifier = checkNotNull(linkifier, "linkifier");
   }
 
@@ -91,7 +89,7 @@
                   "data", new CommitSoyData()
                       .setLinkifier(linkifier)
                       .setRevWalk(walk)
-                      .setArchiveFormat(getArchiveFormat(accessFactory.forRequest(req)))
+                      .setArchiveFormat(getArchiveFormat(getAccess(req)))
                       .toSoyData(req, (RevCommit) obj, COMMIT_SOY_FIELDS, df)));
               break;
             case OBJ_TREE: