Implement Changes.query() method
Change-Id: If5fbc81dab654537503337fb4243dda3fa4927b4
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/change/ChangeIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/change/ChangeIT.java
index d656e1e..a01525a 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/change/ChangeIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/change/ChangeIT.java
@@ -15,8 +15,12 @@
package com.google.gerrit.acceptance.api.change;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
@@ -28,6 +32,8 @@
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.ChangeStatus;
import com.google.gerrit.extensions.common.LabelInfo;
+import com.google.gerrit.extensions.common.ListChangesOption;
+import com.google.gerrit.extensions.common.RevisionInfo;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.reviewdb.client.Account;
@@ -37,6 +43,8 @@
import org.junit.Test;
import java.io.IOException;
+import java.util.EnumSet;
+import java.util.List;
import java.util.Set;
@NoHttpd
@@ -164,4 +172,88 @@
assertEquals(in.branch, info.branch);
assertEquals(in.subject, info.subject);
}
+
+ @Test
+ public void queryChangesNoQuery() throws Exception {
+ PushOneCommit.Result r1 = createChange();
+ PushOneCommit.Result r2 = createChange();
+ List<ChangeInfo> results = gApi.changes().query().get();
+ assertEquals(2, results.size());
+ assertEquals(r2.getChangeId(), results.get(0).changeId);
+ assertEquals(r1.getChangeId(), results.get(1).changeId);
+ }
+
+ @Test
+ public void queryChangesNoResults() throws Exception {
+ createChange();
+ List<ChangeInfo> results = gApi.changes().query("status:open").get();
+ assertEquals(1, results.size());
+ results = gApi.changes().query("status:closed").get();
+ assertTrue(results.isEmpty());
+ }
+
+ @Test
+ public void queryChangesOneTerm() throws Exception {
+ PushOneCommit.Result r1 = createChange();
+ PushOneCommit.Result r2 = createChange();
+ List<ChangeInfo> results = gApi.changes().query("status:open").get();
+ assertEquals(2, results.size());
+ assertEquals(r2.getChangeId(), results.get(0).changeId);
+ assertEquals(r1.getChangeId(), results.get(1).changeId);
+ }
+
+ @Test
+ public void queryChangesMultipleTerms() throws Exception {
+ PushOneCommit.Result r1 = createChange();
+ createChange();
+ List<ChangeInfo> results = gApi.changes()
+ .query("status:open " + r1.getChangeId())
+ .get();
+ assertEquals(r1.getChangeId(), Iterables.getOnlyElement(results).changeId);
+ }
+
+ @Test
+ public void queryChangesLimit() throws Exception {
+ createChange();
+ PushOneCommit.Result r2 = createChange();
+ List<ChangeInfo> results = gApi.changes().query().withLimit(1).get();
+ assertEquals(1, results.size());
+ assertEquals(r2.getChangeId(), Iterables.getOnlyElement(results).changeId);
+ }
+
+ @Test
+ public void queryChangesStart() throws Exception {
+ PushOneCommit.Result r1 = createChange();
+ createChange();
+ List<ChangeInfo> results = gApi.changes().query().withStart(1).get();
+ assertEquals(r1.getChangeId(), Iterables.getOnlyElement(results).changeId);
+ }
+
+ @Test
+ public void queryChangesNoOptions() throws Exception {
+ PushOneCommit.Result r = createChange();
+ ChangeInfo result = Iterables.getOnlyElement(
+ gApi.changes().query(r.getChangeId()).get());
+ assertNull(result.labels);
+ assertNull(result.messages);
+ assertNull(result.revisions);
+ assertNull(result.actions);
+ }
+
+ @Test
+ public void queryChangesOptions() throws Exception {
+ PushOneCommit.Result r = createChange();
+ ChangeInfo result = Iterables.getOnlyElement(gApi.changes()
+ .query(r.getChangeId())
+ .withOptions(EnumSet.allOf(ListChangesOption.class))
+ .get());
+ assertEquals("Code-Review",
+ Iterables.getOnlyElement(result.labels.keySet()));
+ assertEquals(1, result.messages.size());
+ assertFalse(result.actions.isEmpty());
+
+ RevisionInfo rev = Iterables.getOnlyElement(result.revisions.values());
+ assertEquals(r.getPatchSetId().get(), rev._number);
+ assertFalse(rev.actions.isEmpty());
+ }
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/ChangesImpl.java b/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/ChangesImpl.java
index 976228f..0718810 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/ChangesImpl.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/ChangesImpl.java
@@ -14,11 +14,18 @@
package com.google.gerrit.server.api.changes;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
import com.google.gerrit.extensions.api.changes.ChangeApi;
import com.google.gerrit.extensions.api.changes.Changes;
import com.google.gerrit.extensions.common.ChangeInfo;
+import com.google.gerrit.extensions.common.ListChangesOption;
+import com.google.gerrit.extensions.restapi.AuthException;
+import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.IdString;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.TopLevelResource;
@@ -27,23 +34,29 @@
import com.google.gerrit.server.change.ChangesCollection;
import com.google.gerrit.server.change.CreateChange;
import com.google.gerrit.server.project.InvalidChangeOperationException;
+import com.google.gerrit.server.query.change.QueryChanges;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
+import com.google.inject.Provider;
import java.io.IOException;
+import java.util.List;
-class ChangesImpl extends Changes.NotImplemented implements Changes {
+class ChangesImpl implements Changes {
private final ChangesCollection changes;
private final ChangeApiImpl.Factory api;
private final CreateChange.Factory createChangeFactory;
+ private final Provider<QueryChanges> queryProvider;
@Inject
ChangesImpl(ChangesCollection changes,
ChangeApiImpl.Factory api,
- CreateChange.Factory createChangeFactory) {
+ CreateChange.Factory createChangeFactory,
+ Provider<QueryChanges> queryProvider) {
this.changes = changes;
this.api = api;
this.createChangeFactory = createChangeFactory;
+ this.queryProvider = queryProvider;
}
@Override
@@ -82,4 +95,50 @@
throw new RestApiException("Cannot create change", e);
}
}
+
+ @Override
+ public QueryRequest query() {
+ return new QueryRequest() {
+ @Override
+ public List<ChangeInfo> get() throws RestApiException {
+ return ChangesImpl.this.get(this);
+ }
+ };
+ }
+
+ @Override
+ public QueryRequest query(String query) {
+ return query().withQuery(query);
+ }
+
+ private List<ChangeInfo> get(final QueryRequest q) throws RestApiException {
+ QueryChanges qc = queryProvider.get();
+ if (q.getQuery() != null) {
+ qc.addQuery(q.getQuery());
+ }
+ qc.setLimit(q.getLimit());
+ qc.setStart(q.getStart());
+ for (ListChangesOption option : q.getOptions()) {
+ qc.addOption(option);
+ }
+
+ try {
+ List<?> result = qc.apply(TopLevelResource.INSTANCE);
+ if (result.isEmpty()) {
+ return ImmutableList.of();
+ }
+
+ // Check type safety of result; the extension API should be safer than the
+ // REST API in this case, since it's intended to be used in Java.
+ Object first = checkNotNull(result.iterator().next());
+ checkState(first instanceof ChangeJson.ChangeInfo);
+ @SuppressWarnings("unchecked")
+ List<ChangeJson.ChangeInfo> infos = (List<ChangeJson.ChangeInfo>) result;
+
+ return ImmutableList.copyOf(
+ Lists.transform(infos, ChangeInfoMapper.INSTANCE));
+ } catch (BadRequestException | AuthException | OrmException e) {
+ throw new RestApiException("Cannot query changes", e);
+ }
+ }
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/QueryChanges.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/QueryChanges.java
index 41c2e23..fb55b49 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/QueryChanges.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/QueryChanges.java
@@ -106,7 +106,7 @@
}
@Override
- public Object apply(TopLevelResource rsrc)
+ public List<?> apply(TopLevelResource rsrc)
throws BadRequestException, AuthException, OrmException {
List<List<ChangeInfo>> out;
try {