Create Destination using Guice Factory

Destination classes were instantiated in ReplicationFileBasedConfig
which required to have all Destination dependencies injected in
ReplicationFileBasedConfig.

Create Destination using a new DestinationFactory to stop having to
pass dependencies from one class to another.

Also-By: David Pursehouse <dpursehouse@collab.net>
Change-Id: If4d9bc5266837b8fec261decfbd1e651c4cb0f51
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/AutoReloadConfigDecorator.java b/src/main/java/com/googlesource/gerrit/plugins/replication/AutoReloadConfigDecorator.java
index 22b29b1..d9d3901 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/AutoReloadConfigDecorator.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/AutoReloadConfigDecorator.java
@@ -14,14 +14,9 @@
 package com.googlesource.gerrit.plugins.replication;
 
 import com.google.gerrit.common.FileUtil;
-import com.google.gerrit.server.PluginUser;
-import com.google.gerrit.server.account.GroupBackend;
-import com.google.gerrit.server.account.GroupIncludeCache;
 import com.google.gerrit.server.config.SitePaths;
-import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.git.WorkQueue;
 import com.google.inject.Inject;
-import com.google.inject.Injector;
 import com.google.inject.Singleton;
 
 import org.eclipse.jgit.errors.ConfigInvalidException;
@@ -38,38 +33,20 @@
   private ReplicationFileBasedConfig currentConfig;
   private long currentConfigTs;
 
-  private final Injector injector;
   private final SitePaths site;
-  private final RemoteSiteUser.Factory remoteSiteUserFactory;
-  private final PluginUser pluginUser;
-  private final GitRepositoryManager gitRepositoryManager;
-  private final GroupBackend groupBackend;
   private final WorkQueue workQueue;
-  private final ReplicationStateListener stateLog;
-  private final GroupIncludeCache groupIncludeCache;
+  private final DestinationFactory destinationFactory;
 
   @Inject
-  public AutoReloadConfigDecorator(Injector injector,
-      SitePaths site,
-      RemoteSiteUser.Factory ruf,
-      PluginUser pu,
-      GitRepositoryManager grm,
-      GroupBackend gb,
+  public AutoReloadConfigDecorator(SitePaths site,
       WorkQueue workQueue,
-      ReplicationStateListener stateLog,
-      GroupIncludeCache groupIncludeCache)
+      DestinationFactory destinationFactory)
       throws ConfigInvalidException, IOException {
-    this.injector = injector;
     this.site = site;
-    this.remoteSiteUserFactory = ruf;
-    this.pluginUser = pu;
-    this.gitRepositoryManager = grm;
-    this.groupBackend = gb;
-    this.groupIncludeCache = groupIncludeCache;
+    this.destinationFactory = destinationFactory;
     this.currentConfig = loadConfig();
     this.currentConfigTs = getLastModified(currentConfig);
     this.workQueue = workQueue;
-    this.stateLog = stateLog;
   }
 
   private static long getLastModified(ReplicationFileBasedConfig cfg) {
@@ -78,9 +55,7 @@
 
   private ReplicationFileBasedConfig loadConfig()
       throws ConfigInvalidException, IOException {
-    return new ReplicationFileBasedConfig(injector, site, remoteSiteUserFactory,
-        pluginUser, gitRepositoryManager, groupBackend, stateLog,
-        groupIncludeCache);
+    return new ReplicationFileBasedConfig(site, destinationFactory);
   }
 
   private synchronized boolean isAutoReload() {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/DestinationFactory.java b/src/main/java/com/googlesource/gerrit/plugins/replication/DestinationFactory.java
new file mode 100644
index 0000000..dd82aa0
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/DestinationFactory.java
@@ -0,0 +1,56 @@
+// Copyright (C) 2016 The Android Open Source Project
+//
+// 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.googlesource.gerrit.plugins.replication;
+
+import com.google.gerrit.server.PluginUser;
+import com.google.gerrit.server.account.GroupBackend;
+import com.google.gerrit.server.account.GroupIncludeCache;
+import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.Singleton;
+
+@Singleton
+public class DestinationFactory {
+  private final Injector injector;
+  private final RemoteSiteUser.Factory replicationUserFactory;
+  private final PluginUser pluginUser;
+  private final GitRepositoryManager gitRepositoryManager;
+  private final GroupBackend groupBackend;
+  private final ReplicationStateListener stateLog;
+  private final GroupIncludeCache groupIncludeCache;
+
+  @Inject
+  public DestinationFactory(Injector injector,
+      RemoteSiteUser.Factory replicationUserFactory,
+      PluginUser pluginUser,
+      GitRepositoryManager gitRepositoryManager,
+      GroupBackend groupBackend,
+      ReplicationStateListener stateLog,
+      GroupIncludeCache groupIncludeCache) {
+    this.injector = injector;
+    this.replicationUserFactory = replicationUserFactory;
+    this.pluginUser = pluginUser;
+    this.gitRepositoryManager = gitRepositoryManager;
+    this.groupBackend = groupBackend;
+    this.stateLog = stateLog;
+    this.groupIncludeCache = groupIncludeCache;
+  }
+
+  Destination create(DestinationConfiguration config) {
+    return new Destination(injector, config, replicationUserFactory, pluginUser,
+        gitRepositoryManager, groupBackend, stateLog, groupIncludeCache);
+  }
+}
\ No newline at end of file
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationFileBasedConfig.java b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationFileBasedConfig.java
index 1585e43..39bce3d 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationFileBasedConfig.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationFileBasedConfig.java
@@ -17,14 +17,9 @@
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
-import com.google.gerrit.server.PluginUser;
-import com.google.gerrit.server.account.GroupBackend;
-import com.google.gerrit.server.account.GroupIncludeCache;
 import com.google.gerrit.server.config.SitePaths;
-import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.git.WorkQueue;
 import com.google.inject.Inject;
-import com.google.inject.Injector;
 import com.google.inject.Singleton;
 
 import org.eclipse.jgit.errors.ConfigInvalidException;
@@ -52,35 +47,15 @@
   private Path cfgPath;
   private boolean replicateAllOnPluginStart;
   private boolean defaultForceUpdate;
-  private Injector injector;
-  private final RemoteSiteUser.Factory replicationUserFactory;
-  private final PluginUser pluginUser;
-  private final GitRepositoryManager gitRepositoryManager;
-  private final GroupBackend groupBackend;
   private final FileBasedConfig config;
-  private final ReplicationStateListener stateLog;
-  private final GroupIncludeCache groupIncludeCache;
 
   @Inject
-  public ReplicationFileBasedConfig(Injector injector,
-      SitePaths site,
-      RemoteSiteUser.Factory ruf,
-      PluginUser pu,
-      GitRepositoryManager grm,
-      GroupBackend gb,
-      ReplicationStateListener stateLog,
-      GroupIncludeCache groupIncludeCache)
+  public ReplicationFileBasedConfig(SitePaths site,
+      DestinationFactory destinationFactory)
       throws ConfigInvalidException, IOException {
     this.cfgPath = site.etc_dir.resolve("replication.config");
-    this.groupIncludeCache = groupIncludeCache;
-    this.injector = injector;
-    this.replicationUserFactory = ruf;
-    this.pluginUser = pu;
-    this.gitRepositoryManager = grm;
-    this.groupBackend = gb;
     this.config = new FileBasedConfig(cfgPath.toFile(), FS.DETECTED);
-    this.destinations = allDestinations();
-    this.stateLog = stateLog;
+    this.destinations = allDestinations(destinationFactory);
   }
 
   /*
@@ -110,7 +85,7 @@
         .collect(toList());
   }
 
-  private List<Destination> allDestinations()
+  private List<Destination> allDestinations(DestinationFactory destinationFactory)
       throws ConfigInvalidException, IOException {
     if (!config.getFile().exists()) {
       log.warn("Config file " + config.getFile() + " does not exist; not replicating");
@@ -155,10 +130,8 @@
             .setForceUpdate(defaultForceUpdate));
       }
 
-      Destination destination =
-          new Destination(injector, new DestinationConfiguration(c,
-              config), replicationUserFactory, pluginUser,
-              gitRepositoryManager, groupBackend, stateLog, groupIncludeCache);
+      Destination destination = destinationFactory.create(
+          new DestinationConfiguration(c, config));
 
       if (!destination.isSingleProjectMatch()) {
         for (URIish u : c.getURIs()) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationModule.java b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationModule.java
index 5a5f3b4..5434619 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationModule.java
@@ -35,6 +35,7 @@
 class ReplicationModule extends AbstractModule {
   @Override
   protected void configure() {
+    bind(DestinationFactory.class).in(Scopes.SINGLETON);
     bind(ReplicationQueue.class).in(Scopes.SINGLETON);
 
     DynamicSet.bind(binder(), GitReferenceUpdatedListener.class)