Support loading config from a system property

Refactor config loading support into its own static utility method.
Prefer servlet config parameters where available, then fall back to a
system property, then a default filename (gitiles.config in the
working directory).

Change-Id: I90c734dda3d1e582dbee52efede6b688c9197f14
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/GitilesConfig.java b/gitiles-servlet/src/main/java/com/google/gitiles/GitilesConfig.java
new file mode 100644
index 0000000..bf87c4a
--- /dev/null
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/GitilesConfig.java
@@ -0,0 +1,51 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gitiles;
+
+import org.eclipse.jgit.errors.ConfigInvalidException;
+import org.eclipse.jgit.lib.Config;
+import org.eclipse.jgit.storage.file.FileBasedConfig;
+import org.eclipse.jgit.util.FS;
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.servlet.FilterConfig;
+
+public class GitilesConfig {
+  private static final String FILTER_CONFIG_PARAM = "configPath";
+  private static final String PROPERTY_NAME = "com.google.gitiles.configPath";
+  private static final String DEFAULT_PATH = "gitiles.config";
+
+  public static Config loadDefault() throws IOException, ConfigInvalidException {
+    return loadDefault(null);
+  }
+
+  public static Config loadDefault(FilterConfig filterConfig)
+      throws IOException, ConfigInvalidException {
+    String configPath = null;
+    if (filterConfig != null) {
+      configPath = filterConfig.getInitParameter(FILTER_CONFIG_PARAM);
+    }
+    if (configPath == null) {
+      configPath = System.getProperty(PROPERTY_NAME, DEFAULT_PATH);
+    }
+    FileBasedConfig config = new FileBasedConfig(new File(configPath), FS.DETECTED);
+    config.load();
+    return config;
+  }
+
+  private GitilesConfig() {}
+}
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 e2cc699..99a2c4e 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/GitilesFilter.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/GitilesFilter.java
@@ -33,13 +33,11 @@
 import org.eclipse.jgit.http.server.glue.MetaFilter;
 import org.eclipse.jgit.lib.Config;
 import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.storage.file.FileBasedConfig;
 import org.eclipse.jgit.transport.ServiceMayNotContinueException;
 import org.eclipse.jgit.transport.resolver.FileResolver;
 import org.eclipse.jgit.transport.resolver.RepositoryResolver;
 import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
 import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
-import org.eclipse.jgit.util.FS;
 
 import java.io.File;
 import java.io.IOException;
@@ -64,7 +62,6 @@
  * Do not use directly; use {@link GitilesServlet}.
  */
 class GitilesFilter extends MetaFilter {
-  private static final String CONFIG_PATH_PARAM = "configPath";
 
   // The following regexes have the following capture groups:
   // 1. The whole string, which causes RegexPipeline to set REGEX_GROUPS but
@@ -262,18 +259,14 @@
     };
   }
 
-  private void setDefaultFields(FilterConfig config) throws ServletException {
+  private void setDefaultFields(FilterConfig filterConfig) throws ServletException {
     if (renderer != null && urls != null && accessFactory != null && resolver != null
         && visibilityCache != null) {
       return;
     }
-    String configPath = config.getInitParameter(CONFIG_PATH_PARAM);
-    if (configPath == null) {
-      throw new ServletException("Missing required parameter " + configPath);
-    }
-    FileBasedConfig jgitConfig = new FileBasedConfig(new File(configPath), FS.DETECTED);
+    Config config;
     try {
-      jgitConfig.load();
+      config = GitilesConfig.loadDefault(filterConfig);
     } catch (IOException e) {
       throw new ServletException(e);
     } catch (ConfigInvalidException e) {
@@ -281,12 +274,12 @@
     }
 
     if (renderer == null) {
-      String staticPrefix = config.getServletContext().getContextPath() + STATIC_PREFIX;
-      String customTemplates = jgitConfig.getString("gitiles", null, "customTemplates");
-      String siteTitle = Objects.firstNonNull(jgitConfig.getString("gitiles", null, "siteTitle"),
+      String staticPrefix = filterConfig.getServletContext().getContextPath() + STATIC_PREFIX;
+      String customTemplates = config.getString("gitiles", null, "customTemplates");
+      String siteTitle = Objects.firstNonNull(config.getString("gitiles", null, "siteTitle"),
           "Gitiles");
       // TODO(dborowitz): Automatically set to true when run with mvn jetty:run.
-      if (jgitConfig.getBoolean("gitiles", null, "reloadTemplates", false)) {
+      if (config.getBoolean("gitiles", null, "reloadTemplates", false)) {
         renderer = new DebugRenderer(staticPrefix, customTemplates,
             Joiner.on(File.separatorChar).join(System.getProperty("user.dir"),
                 "gitiles-servlet", "src", "main", "resources",
@@ -299,20 +292,20 @@
     if (urls == null) {
       try {
         urls = new DefaultUrls(
-            jgitConfig.getString("gitiles", null, "canonicalHostName"),
-            getBaseGitUrl(jgitConfig),
-            getGerritUrl(jgitConfig));
+            config.getString("gitiles", null, "canonicalHostName"),
+            getBaseGitUrl(config),
+            getGerritUrl(config));
       } catch (UnknownHostException e) {
         throw new ServletException(e);
       }
     }
     linkifier = new Linkifier(urls);
     if (accessFactory == null || resolver == null) {
-      String basePath = jgitConfig.getString("gitiles", null, "basePath");
+      String basePath = config.getString("gitiles", null, "basePath");
       if (basePath == null) {
         throw new ServletException("gitiles.basePath not set");
       }
-      boolean exportAll = jgitConfig.getBoolean("gitiles", null, "exportAll", false);
+      boolean exportAll = config.getBoolean("gitiles", null, "exportAll", false);
 
       FileResolver<HttpServletRequest> fileResolver;
       if (resolver == null) {
@@ -328,7 +321,7 @@
         try {
         accessFactory = new DefaultAccess.Factory(
             new File(basePath),
-            getBaseGitUrl(jgitConfig),
+            getBaseGitUrl(config),
             fileResolver);
         } catch (IOException e) {
           throw new ServletException(e);
@@ -336,9 +329,9 @@
       }
     }
     if (visibilityCache == null) {
-      if (jgitConfig.getSubsections("cache").contains("visibility")) {
+      if (config.getSubsections("cache").contains("visibility")) {
         visibilityCache =
-            new VisibilityCache(false, ConfigUtil.getCacheBuilder(jgitConfig, "visibility"));
+            new VisibilityCache(false, ConfigUtil.getCacheBuilder(config, "visibility"));
       } else {
         visibilityCache = new VisibilityCache(false);
       }