Make ContributorAgreement an AutoValue

Change-Id: I6888e279c8a2a4e748ba2c75fedea7b1476c753d
diff --git a/java/com/google/gerrit/common/data/ContributorAgreement.java b/java/com/google/gerrit/common/data/ContributorAgreement.java
index bc106f0..ed05203 100644
--- a/java/com/google/gerrit/common/data/ContributorAgreement.java
+++ b/java/com/google/gerrit/common/data/ContributorAgreement.java
@@ -14,98 +14,67 @@
 
 package com.google.gerrit.common.data;
 
+import com.google.auto.value.AutoValue;
+import com.google.common.collect.ImmutableList;
+import com.google.gerrit.common.Nullable;
 import com.google.gerrit.entities.Project;
-import java.util.ArrayList;
-import java.util.List;
 
 /** Portion of a {@link Project} describing a single contributor agreement. */
-public class ContributorAgreement implements Comparable<ContributorAgreement> {
-  protected String name;
-  protected String description;
-  protected List<PermissionRule> accepted;
-  protected GroupReference autoVerify;
-  protected String agreementUrl;
-  protected List<String> excludeProjectsRegexes;
-  protected List<String> matchProjectsRegexes;
+@AutoValue
+public abstract class ContributorAgreement implements Comparable<ContributorAgreement> {
+  public abstract String getName();
 
-  protected ContributorAgreement() {}
+  @Nullable
+  public abstract String getDescription();
 
-  public ContributorAgreement(String name) {
-    setName(name);
-  }
+  public abstract ImmutableList<PermissionRule> getAccepted();
 
-  public String getName() {
-    return name;
-  }
+  @Nullable
+  public abstract GroupReference getAutoVerify();
 
-  public void setName(String name) {
-    this.name = name;
-  }
+  @Nullable
+  public abstract String getAgreementUrl();
 
-  public String getDescription() {
-    return description;
-  }
+  public abstract ImmutableList<String> getExcludeProjectsRegexes();
 
-  public void setDescription(String description) {
-    this.description = description;
-  }
+  public abstract ImmutableList<String> getMatchProjectsRegexes();
 
-  public List<PermissionRule> getAccepted() {
-    if (accepted == null) {
-      accepted = new ArrayList<>();
-    }
-    return accepted;
-  }
-
-  public void setAccepted(List<PermissionRule> accepted) {
-    this.accepted = accepted;
-  }
-
-  public GroupReference getAutoVerify() {
-    return autoVerify;
-  }
-
-  public void setAutoVerify(GroupReference autoVerify) {
-    this.autoVerify = autoVerify;
-  }
-
-  public String getAgreementUrl() {
-    return agreementUrl;
-  }
-
-  public void setAgreementUrl(String agreementUrl) {
-    this.agreementUrl = agreementUrl;
-  }
-
-  public List<String> getExcludeProjectsRegexes() {
-    if (excludeProjectsRegexes == null) {
-      excludeProjectsRegexes = new ArrayList<>();
-    }
-    return excludeProjectsRegexes;
-  }
-
-  public void setExcludeProjectsRegexes(List<String> excludeProjectsRegexes) {
-    this.excludeProjectsRegexes = excludeProjectsRegexes;
-  }
-
-  public List<String> getMatchProjectsRegexes() {
-    if (matchProjectsRegexes == null) {
-      matchProjectsRegexes = new ArrayList<>();
-    }
-    return matchProjectsRegexes;
-  }
-
-  public void setMatchProjectsRegexes(List<String> matchProjectsRegexes) {
-    this.matchProjectsRegexes = matchProjectsRegexes;
+  public static ContributorAgreement.Builder builder(String name) {
+    return new AutoValue_ContributorAgreement.Builder()
+        .setName(name)
+        .setAccepted(ImmutableList.of())
+        .setExcludeProjectsRegexes(ImmutableList.of())
+        .setMatchProjectsRegexes(ImmutableList.of());
   }
 
   @Override
-  public int compareTo(ContributorAgreement o) {
+  public final int compareTo(ContributorAgreement o) {
     return getName().compareTo(o.getName());
   }
 
   @Override
-  public String toString() {
+  public final String toString() {
     return "ContributorAgreement[" + getName() + "]";
   }
+
+  public abstract Builder toBuilder();
+
+  @AutoValue.Builder
+  public abstract static class Builder {
+    public abstract Builder setName(String name);
+
+    public abstract Builder setDescription(@Nullable String description);
+
+    public abstract Builder setAccepted(ImmutableList<PermissionRule> accepted);
+
+    public abstract Builder setAutoVerify(@Nullable GroupReference autoVerify);
+
+    public abstract Builder setAgreementUrl(@Nullable String agreementUrl);
+
+    public abstract Builder setExcludeProjectsRegexes(ImmutableList<String> excludeProjectsRegexes);
+
+    public abstract Builder setMatchProjectsRegexes(ImmutableList<String> matchProjectsRegexes);
+
+    public abstract ContributorAgreement build();
+  }
 }
diff --git a/java/com/google/gerrit/server/project/ProjectConfig.java b/java/com/google/gerrit/server/project/ProjectConfig.java
index 9113acc..cc13606 100644
--- a/java/com/google/gerrit/server/project/ProjectConfig.java
+++ b/java/com/google/gerrit/server/project/ProjectConfig.java
@@ -455,16 +455,7 @@
   }
 
   public ContributorAgreement getContributorAgreement(String name) {
-    return getContributorAgreement(name, false);
-  }
-
-  public ContributorAgreement getContributorAgreement(String name, boolean create) {
-    ContributorAgreement ca = contributorAgreements.get(name);
-    if (ca == null && create) {
-      ca = new ContributorAgreement(name);
-      contributorAgreements.put(name, ca);
-    }
-    return ca;
+    return contributorAgreements.get(name);
   }
 
   public Collection<ContributorAgreement> getContributorAgreements() {
@@ -478,14 +469,15 @@
   }
 
   public void replace(ContributorAgreement section) {
-    section.setAutoVerify(resolve(section.getAutoVerify()));
+    ContributorAgreement.Builder ca = section.toBuilder();
+    ca.setAutoVerify(resolve(section.getAutoVerify()));
     ImmutableList.Builder<PermissionRule> newRules = ImmutableList.builder();
     for (PermissionRule rule : section.getAccepted()) {
       newRules.add(rule.toBuilder().setGroup(resolve(rule.getGroup())).build());
     }
-    section.setAccepted(newRules.build());
+    ca.setAccepted(newRules.build());
 
-    contributorAgreements.put(section.getName(), section);
+    contributorAgreements.put(section.getName(), ca.build());
   }
 
   public Collection<NotifyConfig> getNotifyConfigs() {
@@ -514,6 +506,12 @@
     upsertLabelType(builder.build());
   }
 
+  /** Adds or replaces the given {@link ContributorAgreement} in this config. */
+  public void upsertContributorAgreement(ContributorAgreement ca) {
+    contributorAgreements.remove(ca.getName());
+    contributorAgreements.put(ca.getName(), ca);
+  }
+
   public Collection<StoredCommentLinkInfo> getCommentLinkSections() {
     return commentLinkSections.values();
   }
@@ -684,7 +682,7 @@
   private void loadContributorAgreements(Config rc) {
     contributorAgreements = new HashMap<>();
     for (String name : rc.getSubsections(CONTRIBUTOR_AGREEMENT)) {
-      ContributorAgreement ca = getContributorAgreement(name, true);
+      ContributorAgreement.Builder ca = ContributorAgreement.builder(name);
       ca.setDescription(rc.getString(CONTRIBUTOR_AGREEMENT, name, KEY_DESCRIPTION));
       ca.setAgreementUrl(rc.getString(CONTRIBUTOR_AGREEMENT, name, KEY_AGREEMENT_URL));
       ca.setAccepted(loadPermissionRules(rc, CONTRIBUTOR_AGREEMENT, name, KEY_ACCEPTED, false));
@@ -721,6 +719,7 @@
       } else {
         ca.setAutoVerify(rules.get(0).getGroup());
       }
+      contributorAgreements.put(name, ca.build());
     }
   }
 
diff --git a/javatests/com/google/gerrit/acceptance/api/accounts/AgreementsIT.java b/javatests/com/google/gerrit/acceptance/api/accounts/AgreementsIT.java
index 4eb85d8..23fdc0b 100644
--- a/javatests/com/google/gerrit/acceptance/api/accounts/AgreementsIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/accounts/AgreementsIT.java
@@ -76,7 +76,7 @@
 
   protected ContributorAgreement configureContributorAgreement(boolean autoVerify)
       throws Exception {
-    ContributorAgreement ca;
+    ContributorAgreement.Builder ca;
     String name = autoVerify ? "cla-test-group" : "cla-test-no-auto-verify-group";
     AccountGroup.UUID g = groupOperations.newGroup().name(name).create();
     GroupApi groupApi = gApi.groups().id(g.get());
@@ -86,11 +86,11 @@
     PermissionRule rule =
         PermissionRule.builder(groupRef).setAction(PermissionRule.Action.ALLOW).build();
     if (autoVerify) {
-      ca = new ContributorAgreement("cla-test");
+      ca = ContributorAgreement.builder("cla-test");
       ca.setAutoVerify(groupRef);
       ca.setAccepted(ImmutableList.of(rule));
     } else {
-      ca = new ContributorAgreement("cla-test-no-auto-verify");
+      ca = ContributorAgreement.builder("cla-test-no-auto-verify");
     }
     ca.setDescription("description");
     ca.setAgreementUrl("agreement-url");
@@ -98,9 +98,10 @@
     ca.setExcludeProjectsRegexes(ImmutableList.of("ExcludedProject"));
 
     try (ProjectConfigUpdate u = updateProject(allProjects)) {
-      u.getConfig().replace(ca);
+      ContributorAgreement contributorAgreement = ca.build();
+      u.getConfig().replace(contributorAgreement);
       u.save();
-      return ca;
+      return contributorAgreement;
     }
   }
 
diff --git a/javatests/com/google/gerrit/server/project/ProjectConfigTest.java b/javatests/com/google/gerrit/server/project/ProjectConfigTest.java
index d7e47ce..b7125c3 100644
--- a/javatests/com/google/gerrit/server/project/ProjectConfigTest.java
+++ b/javatests/com/google/gerrit/server/project/ProjectConfigTest.java
@@ -309,12 +309,13 @@
             Collections.singletonList(PermissionRule.create(cfg.resolve(staff))));
     Permission submit = section.getPermission(Permission.SUBMIT);
     submit.add(PermissionRule.create(cfg.resolve(staff)));
-    ContributorAgreement ca = cfg.getContributorAgreement("Individual");
-    ca.setAccepted(Collections.singletonList(PermissionRule.create(cfg.resolve(staff))));
+    ContributorAgreement.Builder ca = cfg.getContributorAgreement("Individual").toBuilder();
+    ca.setAccepted(ImmutableList.of(PermissionRule.create(cfg.resolve(staff))));
     ca.setAutoVerify(null);
-    ca.setMatchProjectsRegexes(null);
-    ca.setExcludeProjectsRegexes(Collections.singletonList("^/theirproject"));
+    ca.setMatchProjectsRegexes(ImmutableList.of());
+    ca.setExcludeProjectsRegexes(ImmutableList.of("^/theirproject"));
     ca.setDescription("A new description");
+    cfg.upsertContributorAgreement(ca.build());
     rev = commit(cfg);
     assertThat(text(rev, "project.config"))
         .isEqualTo(
@@ -714,8 +715,9 @@
     update(rev);
 
     ProjectConfig cfg = read(rev);
-    ContributorAgreement section = cfg.getContributorAgreement("Individual");
+    ContributorAgreement.Builder section = cfg.getContributorAgreement("Individual").toBuilder();
     section.setAccepted(ImmutableList.of());
+    cfg.upsertContributorAgreement(section.build());
     rev = commit(cfg);
     assertThat(text(rev, "project.config"))
         .isEqualTo(