Refactor: introduce Change class

This prepares a following commit that fixes the merge of non mergeable
crossrepos when processing RefUpdatedEvent.

Change-Id: Id608b41f8df9c751d12e04f53d32e4970c231a65
diff --git a/src/main/java/com/criteo/gerrit/plugins/automerge/AtomicityHelper.java b/src/main/java/com/criteo/gerrit/plugins/automerge/AtomicityHelper.java
index 0d59513..5cadfbf 100644
--- a/src/main/java/com/criteo/gerrit/plugins/automerge/AtomicityHelper.java
+++ b/src/main/java/com/criteo/gerrit/plugins/automerge/AtomicityHelper.java
@@ -2,10 +2,8 @@
 
 import com.google.gerrit.common.data.SubmitRecord;
 import com.google.gerrit.extensions.api.changes.SubmitInput;
-import com.google.gerrit.extensions.common.ChangeInfo;
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.IdentifiedUser;
@@ -16,7 +14,6 @@
 import com.google.gerrit.server.change.PostReview;
 import com.google.gerrit.server.change.RevisionResource;
 import com.google.gerrit.server.change.Submit;
-import com.google.gerrit.server.data.ChangeAttribute;
 import com.google.gerrit.server.git.MergeUtil;
 import com.google.gerrit.server.project.ChangeControl;
 import com.google.gerrit.server.project.NoSuchChangeException;
@@ -95,7 +92,7 @@
    * @param change a ChangeAttribute instance
    * @return true or false
    */
-  public boolean isAtomicReview(final ChangeAttribute change) {
+  public boolean isAtomicReview(final Change change) {
     final boolean atomic = change.topic != null && change.topic.startsWith(config.getTopicPrefix());
     log.debug(String.format("Checking if change %s is an atomic change: %b", change.number, atomic));
     return atomic;
@@ -110,7 +107,7 @@
    * @throws OrmException
    */
   public boolean isSubmittable(String project, int change) throws OrmException {
-    ChangeData changeData = changeDataFactory.create(db.get(), new Project.NameKey(project), new Change.Id(change));
+    ChangeData changeData = changeDataFactory.create(db.get(), new Project.NameKey(project), new com.google.gerrit.reviewdb.client.Change.Id(change));
     // For draft reviews, the patchSet must be set to avoid an NPE.
     final List<SubmitRecord> cansubmit = new SubmitRuleEvaluator(changeData).setPatchSet(changeData.currentPatchSet()).evaluate();
     log.debug(String.format("Checking if change %d is submitable.", change));
@@ -142,8 +139,8 @@
   }
 
   public RevisionResource getRevisionResource(String project, int changeNumber) throws NoSuchChangeException, OrmException {
-    ChangeControl ctl = changeFactory.validateFor(db.get(), new Change.Id(changeNumber), getBotUser());
-    ChangeData changeData = changeDataFactory.create(db.get(), new Project.NameKey(project), new Change.Id(changeNumber));
+    ChangeControl ctl = changeFactory.validateFor(db.get(), new com.google.gerrit.reviewdb.client.Change.Id(changeNumber), getBotUser());
+    ChangeData changeData = changeDataFactory.create(db.get(), new Project.NameKey(project), new com.google.gerrit.reviewdb.client.Change.Id(changeNumber));
     RevisionResource r = new RevisionResource(collection.parse(ctl), changeData.currentPatchSet());
     return r;
   }
diff --git a/src/main/java/com/criteo/gerrit/plugins/automerge/AutomaticMerger.java b/src/main/java/com/criteo/gerrit/plugins/automerge/AutomaticMerger.java
index 83e26dd..71097aa 100644
--- a/src/main/java/com/criteo/gerrit/plugins/automerge/AutomaticMerger.java
+++ b/src/main/java/com/criteo/gerrit/plugins/automerge/AutomaticMerger.java
@@ -106,7 +106,7 @@
 
 
   private void onTopicChanged(final TopicChangedEvent event) {
-    ChangeAttribute change = event.change.get();
+    Change change = Change.from(event.change.get());
     if (!atomicityHelper.isAtomicReview(change)) {
       return;
     }
@@ -114,7 +114,7 @@
   }
 
   private void onPatchSetCreated(final PatchSetCreatedEvent event) {
-    ChangeAttribute change = event.change.get();
+    Change change = Change.from(event.change.get());
     if (atomicityHelper.isAtomicReview(change)) {
       processNewAtomicPatchSet(change);
     }
@@ -134,7 +134,7 @@
     ChangeAttribute change = newComment.change.get();
     try {
       checkReviewExists(change.number);
-      autoSubmitIfMergeable(change);
+      autoSubmitIfMergeable(Change.from(change));
     } catch (RestApiException | OrmException | UpdateException | IOException e) {
       log.error("An exception occured while trying to atomic merge a change.", e);
       throw new RuntimeException(e);
@@ -177,7 +177,7 @@
     }
   }
 
-  private void autoSubmitIfMergeable(ChangeAttribute change)
+  private void autoSubmitIfMergeable(Change change)
       throws OrmException, RestApiException, NoSuchChangeException, IOException, UpdateException {
     if (atomicityHelper.isSubmittable(change.project, change.number)) {
       if (atomicityHelper.isAtomicReview(change)) {
@@ -216,7 +216,7 @@
     return false;
   }
 
-  private void attemptToMergeAtomic(ChangeAttribute change)
+  private void attemptToMergeAtomic(Change change)
       throws RestApiException, OrmException, NoSuchChangeException, IOException, UpdateException {
     final List<ChangeInfo> related = Lists.newArrayList();
     related.addAll(
@@ -247,7 +247,7 @@
     }
   }
 
-  private void processNewAtomicPatchSet(ChangeAttribute change) {
+  private void processNewAtomicPatchSet(Change change) {
     try {
       checkReviewExists(change.number);
       if (atomicityHelper.hasDependentReview(change.project, change.number)) {
diff --git a/src/main/java/com/criteo/gerrit/plugins/automerge/Change.java b/src/main/java/com/criteo/gerrit/plugins/automerge/Change.java
new file mode 100644
index 0000000..a3e91e5
--- /dev/null
+++ b/src/main/java/com/criteo/gerrit/plugins/automerge/Change.java
@@ -0,0 +1,30 @@
+package com.criteo.gerrit.plugins.automerge;
+
+import com.google.gerrit.extensions.common.ChangeInfo;
+import com.google.gerrit.server.data.ChangeAttribute;
+
+/**
+ * A change represented only with the fields that this plugin requires.
+ * <p>
+ * As a change can be a {@link ChangeAttribute} or a {@link ChangeInfo}, this intermediate class is
+ * needed.
+ */
+public class Change {
+  public final String project;
+  public final int number;
+  public final String topic;
+
+  private Change(String project, int number, String topic) {
+    this.project = project;
+    this.number = number;
+    this.topic = topic;
+  }
+
+  static public Change from(ChangeAttribute changeAttribute) {
+    return new Change(changeAttribute.project, changeAttribute.number, changeAttribute.topic);
+  }
+
+  static public Change from(ChangeInfo changeInfo) {
+    return new Change(changeInfo.project, changeInfo._number, changeInfo.topic);
+  }
+}