Expose GitilesAccess.getAccess on interface

These helpers allow callers to obtain the GitilesAccess outside of the
context of being a subclass of BaseServlet.  The Optional form exists
for callers that can reasonably assume some prior logic has already
setup the GitilesAccess for the request.

Change-Id: Ie28bd75746b0c6f1d2f425b964ca9743fad1c74b
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 387a15f..bf19e88 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/BaseServlet.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/BaseServlet.java
@@ -52,7 +52,6 @@
 /** Base servlet class for Gitiles servlets that serve Soy templates. */
 public abstract class BaseServlet extends HttpServlet {
   private static final long serialVersionUID = 1L;
-  private static final String ACCESS_ATTRIBUTE = BaseServlet.class.getName() + "/GitilesAccess";
   private static final String DATA_ATTRIBUTE = BaseServlet.class.getName() + "/Data";
   private static final String STREAMING_ATTRIBUTE = BaseServlet.class.getName() + "/Streaming";
 
@@ -366,12 +365,7 @@
   }
 
   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;
+    return GitilesAccess.getAccess(req, accessFactory);
   }
 
   protected void setCacheHeaders(HttpServletRequest req, HttpServletResponse res) {
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/GitilesAccess.java b/gitiles-servlet/src/main/java/com/google/gitiles/GitilesAccess.java
index ec3b5ff..505098a 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/GitilesAccess.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/GitilesAccess.java
@@ -16,6 +16,7 @@
 
 import java.io.IOException;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
 import javax.annotation.Nullable;
 import javax.servlet.http.HttpServletRequest;
@@ -30,6 +31,21 @@
  * information about the host and repository.
  */
 public interface GitilesAccess {
+  /** Access for the current request, if it has been initialized. */
+  public static Optional<GitilesAccess> getAccess(HttpServletRequest req) {
+    return Optional.ofNullable((GitilesAccess) req.getAttribute(GitilesAccess.class.getName()));
+  }
+
+  /** Access for the current request. */
+  public static GitilesAccess getAccess(HttpServletRequest req, Factory factory) {
+    GitilesAccess access = getAccess(req).orElse(null);
+    if (access == null) {
+      access = factory.forRequest(req);
+      req.setAttribute(GitilesAccess.class.getName(), access);
+    }
+    return access;
+  }
+
   /** Factory for per-request access. */
   public interface Factory {
     GitilesAccess forRequest(HttpServletRequest req);