Pass around ProjectConfig instead of ProjectState

There is an ongoing effort to make ProjectState immutable and we use
ProjectConfig as an object directly in other places where we update it.
Therefore, pass around ProjectConfig instead of ProjectState.

Change-Id: Ie78f3869a7ac511d639d1040dbc273c2a6253c3d
diff --git a/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/config/ConfigServlet.java b/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/config/ConfigServlet.java
index 87c7b08..9721b1e 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/config/ConfigServlet.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/config/ConfigServlet.java
@@ -18,17 +18,20 @@
 import com.google.gerrit.extensions.restapi.BadRequestException;
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.git.meta.MetaDataUpdate;
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.permissions.ProjectPermission;
 import com.google.gerrit.server.project.ProjectCache;
+import com.google.gerrit.server.project.ProjectConfig;
 import com.google.gerrit.server.project.ProjectResource;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import com.googlesource.gerrit.plugins.simplesubmitrules.api.SubmitConfig;
 import java.io.IOException;
+import org.eclipse.jgit.errors.ConfigInvalidException;
 
 /** REST Endpoint to configure labels and our simple submit rules */
 @Singleton
@@ -63,20 +66,22 @@
 
   @Override
   public Object apply(ProjectResource resource, SubmitConfig inConfig)
-      throws PermissionBackendException, AuthException, BadRequestException, IOException {
-
+      throws PermissionBackendException, AuthException, BadRequestException, ConfigInvalidException,
+          IOException {
+    Project.NameKey projectName = resource.getNameKey();
     permissionBackend
         .user(resource.getUser())
         .project(resource.getNameKey())
         .check(ProjectPermission.WRITE_CONFIG);
 
     IdentifiedUser user = resource.getUser().asIdentifiedUser();
-    try (MetaDataUpdate md = metaDataUpdateFactory.create(resource.getNameKey(), user)) {
-      configTranslator.applyTo(inConfig, resource.getProjectState());
-      resource.getProjectState().getConfig().commit(md);
-      projectCache.evict(resource.getNameKey());
+    try (MetaDataUpdate md = metaDataUpdateFactory.create(projectName, user)) {
+      ProjectConfig projectConfig = ProjectConfig.read(md);
+      configTranslator.applyTo(inConfig, projectConfig);
+      projectConfig.commit(md);
+      projectCache.evict(projectName);
     }
 
-    return configTranslator.convertFrom(projectCache.get(resource.getNameKey()));
+    return configTranslator.convertFrom(projectCache.checkedGet(projectName));
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/config/ConfigTranslator.java b/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/config/ConfigTranslator.java
index f7ff9b0..d9dea99 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/config/ConfigTranslator.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/simplesubmitrules/config/ConfigTranslator.java
@@ -24,6 +24,7 @@
 import com.google.gerrit.extensions.restapi.BadRequestException;
 import com.google.gerrit.server.config.PluginConfig;
 import com.google.gerrit.server.config.PluginConfigFactory;
+import com.google.gerrit.server.project.ProjectCache;
 import com.google.gerrit.server.project.ProjectConfig;
 import com.google.gerrit.server.project.ProjectState;
 import com.google.inject.Inject;
@@ -32,6 +33,7 @@
 import com.googlesource.gerrit.plugins.simplesubmitrules.api.CommentsRules;
 import com.googlesource.gerrit.plugins.simplesubmitrules.api.LabelDefinition;
 import com.googlesource.gerrit.plugins.simplesubmitrules.api.SubmitConfig;
+import java.io.IOException;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
@@ -39,11 +41,16 @@
 /** Codec class used to convert {@link SubmitConfig} from/to a Gerrit config */
 @Singleton
 public final class ConfigTranslator {
+  private final ProjectCache projectCache;
   private final PluginConfigFactory pluginConfigFactory;
   private final String pluginName;
 
   @Inject
-  public ConfigTranslator(PluginConfigFactory pluginConfigFactory, @PluginName String pluginName) {
+  public ConfigTranslator(
+      ProjectCache projectCache,
+      PluginConfigFactory pluginConfigFactory,
+      @PluginName String pluginName) {
+    this.projectCache = projectCache;
     this.pluginConfigFactory = pluginConfigFactory;
     this.pluginName = pluginName;
   }
@@ -114,26 +121,30 @@
     return submitConfig;
   }
 
-  void applyTo(SubmitConfig inConfig, ProjectState projectState) throws BadRequestException {
+  void applyTo(SubmitConfig inConfig, ProjectConfig projectConfig)
+      throws BadRequestException, IOException {
     PluginConfig hostPluginConfig = pluginConfigFactory.getFromGerritConfig(pluginName);
-    PluginConfig projectPluginConfig =
-        pluginConfigFactory.getFromProjectConfig(projectState, pluginName);
+    PluginConfig projectPluginConfig = projectConfig.getPluginConfig(pluginName);
+
     applyCommentRulesTo(inConfig.comments, projectPluginConfig);
-    applyLabelsTo(inConfig.labels, projectState, hostPluginConfig);
+    applyLabelsTo(inConfig.labels, projectConfig, hostPluginConfig);
   }
 
-  private static void applyLabelsTo(
-      Map<String, LabelDefinition> labels, ProjectState projectState, PluginConfig hostPluginConfig)
-      throws BadRequestException {
+  private void applyLabelsTo(
+      Map<String, LabelDefinition> labels,
+      ProjectConfig projectConfig,
+      PluginConfig hostPluginConfig)
+      throws BadRequestException, IOException {
     if (labels.isEmpty()) {
       return;
     }
 
     for (Map.Entry<String, LabelDefinition> entry : labels.entrySet()) {
-      if (!projectState.getConfig().getLabelSections().containsKey(entry.getKey())) {
+      if (!projectConfig.getLabelSections().containsKey(entry.getKey())) {
         // The current project does not have this label. Try to copy it down from the inherited
         // labels to be able to modify it locally.
-        Map<String, LabelType> copiedLabelTypes = projectState.getConfig().getLabelSections();
+        Map<String, LabelType> copiedLabelTypes = projectConfig.getLabelSections();
+        ProjectState projectState = projectCache.checkedGet(projectConfig.getName());
         projectState
             .getLabelTypes()
             .getLabelTypes()
@@ -145,7 +156,7 @@
 
       String label = entry.getKey();
       LabelDefinition definition = entry.getValue();
-      LabelType labelType = projectState.getConfig().getLabelSections().get(label);
+      LabelType labelType = projectConfig.getLabelSections().get(label);
 
       if (labelType == null) {
         throw new BadRequestException(