Associated GitRepositoryManager indirectly through a Named binding

Allow to have different implementations of the GitRepositoryManager
through a named binding. This allows to have the caller to
have additional logic on the wrapped local disk implementation,
such as MultiBase or Cached refdb.

Change-Id: I5d5e6fb8e552a9bc82b1686636dbfb1c6f7365de
diff --git a/pom.xml b/pom.xml
index 5dfaa93..55f29fd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
 
     <groupId>com.gerritforge</groupId>
     <artifactId>global-refdb</artifactId>
-    <version>3.4.4.2</version>
+    <version>3.4.4.3</version>
     <packaging>jar</packaging>
 
     <name>global-refdb</name>
diff --git a/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/SharedRefDbConfiguration.java b/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/SharedRefDbConfiguration.java
index a607cdc..0cb78b6 100644
--- a/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/SharedRefDbConfiguration.java
+++ b/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/SharedRefDbConfiguration.java
@@ -23,6 +23,8 @@
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Multimap;
 import com.google.common.collect.MultimapBuilder;
+import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.git.LocalDiskRepositoryManager;
 import java.io.IOException;
 import java.util.List;
 import org.eclipse.jgit.errors.ConfigInvalidException;
@@ -41,6 +43,7 @@
   private final Supplier<Projects> projects;
   private final Supplier<SharedRefDatabase> sharedRefDb;
   private final String pluginName;
+  private final String localDiskRepositoryManagerClassName;
 
   /**
    * Constructs a {@code SharedRefDbConfiguration} by providing the libModule name and a 'config'
@@ -54,6 +57,13 @@
     projects = memoize(() -> new Projects(lazyCfg));
     sharedRefDb = memoize(() -> new SharedRefDatabase(lazyCfg));
     this.pluginName = pluginName;
+    localDiskRepositoryManagerClassName =
+        lazyCfg
+            .get()
+            .getString(
+                SharedRefDatabase.SECTION,
+                null,
+                SharedRefDatabase.LOCAL_DISK_REPOSITORY_MANAGER_CLASS);
   }
 
   /**
@@ -92,6 +102,15 @@
     return ofInstance(config);
   }
 
+  public Class<? extends GitRepositoryManager> getLocalRepositoryManager()
+      throws ClassNotFoundException {
+    if (localDiskRepositoryManagerClassName != null) {
+      return (Class<? extends GitRepositoryManager>)
+          Class.forName(localDiskRepositoryManagerClassName);
+    }
+    return LocalDiskRepositoryManager.class;
+  }
+
   /**
    * Represents the global refdb configuration, which is computed by reading the 'ref-database'
    * section from the configuration file of this library's consumers. It allows to specify whether
@@ -102,6 +121,8 @@
     public static final String SECTION = "ref-database";
     public static final String ENABLE_KEY = "enabled";
     public static final String SUBSECTION_ENFORCEMENT_RULES = "enforcementRules";
+    public static final String LOCAL_DISK_REPOSITORY_MANAGER_CLASS =
+        "localDiskRepositoryManagerClass";
 
     private final boolean enabled;
     private final Multimap<EnforcePolicy, String> enforcementRules;
diff --git a/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/SharedRefDbGitRepositoryManager.java b/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/SharedRefDbGitRepositoryManager.java
index 4f13d6e..da277e2 100644
--- a/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/SharedRefDbGitRepositoryManager.java
+++ b/src/main/java/com/gerritforge/gerrit/globalrefdb/validation/SharedRefDbGitRepositoryManager.java
@@ -17,7 +17,6 @@
 import com.google.common.collect.ImmutableSet;
 import com.google.gerrit.entities.Project;
 import com.google.gerrit.server.git.GitRepositoryManager;
-import com.google.gerrit.server.git.LocalDiskRepositoryManager;
 import com.google.gerrit.server.git.RepositoryCaseMismatchException;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
@@ -49,6 +48,8 @@
    */
   public static final String IGNORED_REFS = "ignored_refs";
 
+  public static final String LOCAL_DISK_REPOSITORY_MANAGER = "local_disk_repository_manager";
+
   private final GitRepositoryManager gitRepositoryManager;
   private final SharedRefDbRepository.Factory sharedRefDbRepoFactory;
 
@@ -68,7 +69,7 @@
   @Inject
   public SharedRefDbGitRepositoryManager(
       SharedRefDbRepository.Factory sharedRefDbRepoFactory,
-      LocalDiskRepositoryManager localDiskRepositoryManager) {
+      @Named(LOCAL_DISK_REPOSITORY_MANAGER) GitRepositoryManager localDiskRepositoryManager) {
     this.sharedRefDbRepoFactory = sharedRefDbRepoFactory;
     this.gitRepositoryManager = localDiskRepositoryManager;
   }
diff --git a/src/test/java/com/gerritforge/gerrit/globalrefdb/validation/SharedRefDbGitRepositoryManagerTest.java b/src/test/java/com/gerritforge/gerrit/globalrefdb/validation/SharedRefDbGitRepositoryManagerTest.java
index a6c7667..34f39c8 100644
--- a/src/test/java/com/gerritforge/gerrit/globalrefdb/validation/SharedRefDbGitRepositoryManagerTest.java
+++ b/src/test/java/com/gerritforge/gerrit/globalrefdb/validation/SharedRefDbGitRepositoryManagerTest.java
@@ -19,6 +19,7 @@
 
 import com.gerritforge.gerrit.globalrefdb.validation.dfsrefdb.RefFixture;
 import com.google.common.collect.ImmutableSet;
+import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.git.LocalDiskRepositoryManager;
 import com.google.inject.AbstractModule;
 import com.google.inject.Guice;
@@ -120,7 +121,10 @@
                 .annotatedWith(Names.named(SharedRefDbGitRepositoryManager.IGNORED_REFS))
                 .toInstance(ignoredRefs);
             bind(SharedRefDbRepository.Factory.class).toInstance(sharedRefDbRepositoryFactoryMock);
-            bind(LocalDiskRepositoryManager.class).toInstance(localDiskRepositoryManagerMock);
+            bind(GitRepositoryManager.class)
+                .annotatedWith(
+                    Names.named(SharedRefDbGitRepositoryManager.LOCAL_DISK_REPOSITORY_MANAGER))
+                .toInstance(localDiskRepositoryManagerMock);
           }
         });
   }
diff --git a/src/test/java/com/gerritforge/gerrit/globalrefdb/validation/ValidationModuleTest.java b/src/test/java/com/gerritforge/gerrit/globalrefdb/validation/ValidationModuleTest.java
index b1af798..eb84739 100644
--- a/src/test/java/com/gerritforge/gerrit/globalrefdb/validation/ValidationModuleTest.java
+++ b/src/test/java/com/gerritforge/gerrit/globalrefdb/validation/ValidationModuleTest.java
@@ -23,6 +23,8 @@
 import com.google.gerrit.acceptance.TestPlugin;
 import com.google.gerrit.extensions.config.FactoryModule;
 import com.google.gerrit.server.config.GerritServerConfig;
+import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.git.LocalDiskRepositoryManager;
 import com.google.inject.*;
 import com.google.inject.name.Names;
 import java.util.Optional;
@@ -105,6 +107,9 @@
       bind(SharedRefDbConfiguration.class).toInstance(cfg);
       bind(ValidationMetrics.class);
 
+      bind(GitRepositoryManager.class)
+          .annotatedWith(Names.named(SharedRefDbGitRepositoryManager.LOCAL_DISK_REPOSITORY_MANAGER))
+          .to(LocalDiskRepositoryManager.class);
       bind(SharedRefDbGitRepositoryManager.class);
       bind(SharedRefEnforcement.class).to(DefaultSharedRefEnforcement.class).in(Scopes.SINGLETON);
     }