[project.config] Allow to add commentLink entries

Change-Id: I2fd01cb6775a905d7e602d5415102b274bd98fd3
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java
index bae7ed7..12a62f9 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java
@@ -394,6 +394,10 @@
     return commentLinkSections;
   }
 
+  public void addCommentLinkSection(CommentLinkInfoImpl commentLink) {
+    commentLinkSections.add(commentLink);
+  }
+
   public ConfiguredMimeTypes getMimeTypes() {
     return mimeTypes;
   }
@@ -916,7 +920,6 @@
                     rc.getString(COMMENTLINK, name, KEY_MATCH), name, e.getMessage())));
       }
     }
-    commentLinkSections = ImmutableList.copyOf(commentLinkSections);
   }
 
   private void loadSubscribeSections(Config rc) throws ConfigInvalidException {
@@ -1079,6 +1082,7 @@
     savePluginSections(rc, keepGroups);
     groupList.retainUUIDs(keepGroups);
     saveLabelSections(rc);
+    saveCommentLinkSections(rc);
     saveSubscribeSections(rc);
 
     saveConfig(PROJECT_CONFIG, rc);
@@ -1349,6 +1353,23 @@
     }
   }
 
+  private void saveCommentLinkSections(Config rc) {
+    if (commentLinkSections != null) {
+      for (CommentLinkInfoImpl cm : commentLinkSections) {
+        rc.setString(COMMENTLINK, cm.name, KEY_MATCH, cm.match);
+        if (!Strings.isNullOrEmpty(cm.html)) {
+          rc.setString(COMMENTLINK, cm.name, KEY_HTML, cm.html);
+        }
+        if (!Strings.isNullOrEmpty(cm.link)) {
+          rc.setString(COMMENTLINK, cm.name, KEY_LINK, cm.link);
+        }
+        if (cm.enabled != null && !cm.enabled) {
+          rc.setBoolean(COMMENTLINK, cm.name, KEY_ENABLED, cm.enabled);
+        }
+      }
+    }
+  }
+
   private static void setBooleanConfigKey(
       Config rc, String name, String key, boolean value, boolean defaultValue) {
     if (value == defaultValue) {
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/git/ProjectConfigTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/git/ProjectConfigTest.java
index 2519a7f..ad9a1ce 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/git/ProjectConfigTest.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/git/ProjectConfigTest.java
@@ -29,6 +29,7 @@
 import com.google.gerrit.reviewdb.client.RefNames;
 import com.google.gerrit.server.config.PluginConfig;
 import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
+import com.google.gerrit.server.project.CommentLinkInfoImpl;
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.Collections;
@@ -476,6 +477,19 @@
                 + "\n");
   }
 
+  @Test
+  public void addCommentLink() throws Exception {
+    RevCommit rev = util.commit().create();
+    update(rev);
+
+    ProjectConfig cfg = read(rev);
+    CommentLinkInfoImpl cm = new CommentLinkInfoImpl("Test", "abc.*", null, "<a>link</a>", true);
+    cfg.addCommentLinkSection(cm);
+    rev = commit(cfg);
+    assertThat(text(rev, "project.config"))
+        .isEqualTo("[commentlink \"Test\"]\n\tmatch = abc.*\n\thtml = <a>link</a>\n");
+  }
+
   private ProjectConfig read(RevCommit rev) throws IOException, ConfigInvalidException {
     ProjectConfig cfg = new ProjectConfig(new Project.NameKey("test"));
     cfg.load(db, rev);