Add AtomicityHelper class
This class add some helper to check dependencies between changes
and there atomicity.
diff --git a/src/main/java/com/criteo/gerrit/plugins/automerge/AtomicityHelper.java b/src/main/java/com/criteo/gerrit/plugins/automerge/AtomicityHelper.java
new file mode 100644
index 0000000..c038afb
--- /dev/null
+++ b/src/main/java/com/criteo/gerrit/plugins/automerge/AtomicityHelper.java
@@ -0,0 +1,117 @@
+package com.criteo.gerrit.plugins.automerge;
+
+import com.google.gerrit.common.data.SubmitRecord;
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.reviewdb.server.ReviewDb;
+import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.account.AccountByEmailCache;
+import com.google.gerrit.server.change.ChangesCollection;
+import com.google.gerrit.server.change.GetRelated;
+import com.google.gerrit.server.change.GetRelated.RelatedInfo;
+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;
+import com.google.gerrit.server.query.change.ChangeData;
+import com.google.gwtorm.server.OrmException;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Set;
+
+public class AtomicityHelper {
+
+ @Inject
+ private AccountByEmailCache byEmailCache;
+
+ @Inject
+ ChangeData.Factory changeDataFactory;
+
+ @Inject
+ private ChangeControl.GenericFactory changeFactory;
+
+ @Inject
+ private ChangesCollection collection;
+
+ AutomergeConfig config;
+
+ @Inject
+ Provider<ReviewDb> db;
+
+ @Inject
+ private IdentifiedUser.GenericFactory factory;
+
+ @Inject
+ GetRelated getRelated;
+
+ @Inject
+ MergeUtil.Factory mergeUtilFactory;
+
+ @Inject
+ Provider<PostReview> reviewer;
+
+ @Inject
+ Submit submitter;
+
+ public AtomicityHelper(final AutomergeConfig config) {
+ this.config = config;
+ }
+
+ /**
+ * Check if the current patchset of the specified change has dependent
+ * unmerged changes.
+ *
+ * @param number
+ * @return true or false
+ * @throws IOException
+ * @throws NoSuchChangeException
+ * @throws OrmException
+ */
+ public boolean hasDependentReview(final int number) throws IOException, NoSuchChangeException, OrmException {
+ final Set<Account.Id> ids = byEmailCache.get(config.getBotEmail());
+ final IdentifiedUser qabot = factory.create(ids.iterator().next());
+ final ChangeControl ctl = changeFactory.controlFor(new Change.Id(number), qabot);
+ final ChangeData changeData = changeDataFactory.create(db.get(), new Change.Id(number));
+
+ final RevisionResource r = new RevisionResource(collection.parse(ctl), changeData.currentPatchSet());
+ final RelatedInfo related = getRelated.apply(r);
+
+ return related.changes.size() > 0;
+ }
+
+ /**
+ * Check if a change is an atomic change or not. A change is atomic if it has
+ * the atomic topic prefix.
+ *
+ * @param change a ChangeAttribute instance
+ * @return true or false
+ */
+ public boolean isAtomicReview(final ChangeAttribute change) {
+ return change.topic != null && change.topic.startsWith(config.getTopicPrefix());
+ }
+
+ /**
+ * Check if a change is submitable.
+ *
+ * @param change a change number
+ * @return true or false
+ * @throws OrmException
+ */
+ public boolean isSubmittable(final int change) throws OrmException {
+ final ChangeData changeData = changeDataFactory.create(db.get(), new Change.Id(change));
+ final List<SubmitRecord> cansubmit = changeData.changeControl().canSubmit(db.get(), changeData.currentPatchSet());
+
+ for (final SubmitRecord submit : cansubmit) {
+ if (submit.status != SubmitRecord.Status.OK) {
+ return false;
+ }
+ }
+ return true;
+ }
+}