Set '_more_groups' on last group of query result

If the number of groups matching the query exceeds the limit the
last group has a '_more_groups: true' JSON field set.

Change-Id: I6f1fcda58813e2c7b5dc788d88b989c377afec7e
Signed-off-by: Edwin Kempin <ekempin@google.com>
diff --git a/Documentation/rest-api-groups.txt b/Documentation/rest-api-groups.txt
index 1cfcb55..a2d2ff2 100644
--- a/Documentation/rest-api-groups.txt
+++ b/Documentation/rest-api-groups.txt
@@ -249,6 +249,10 @@
   ]
 ----
 
+If the number of groups matching the query exceeds either the internal
+limit or a supplied `limit` query parameter, the last group object has
+a `_more_groups: true` JSON field set.
+
 [[group-query-limit]]
 ==== Group Limit
 The `/groups/?query2=<query>` URL also accepts a limit integer in the
@@ -1341,6 +1345,10 @@
 |`group_id`    |only for internal groups|The numeric ID of the group.
 |`owner`       |only for internal groups|The name of the owner group.
 |`owner_id`    |only for internal groups|The URL encoded UUID of the owner group.
+|`_more_groups`|optional, only for internal groups, not set if `false`|
+Whether the query would deliver more results if not limited. +
+Only set on the last group that is returned by a
+link:#query-groups[group query].
 |`members`     |optional, only for internal groups|
 A list of link:rest-api-accounts.html#account-info[AccountInfo]
 entities describing the direct members. +
diff --git a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/common/GroupInfo.java b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/common/GroupInfo.java
index f956a03..55fb92a 100644
--- a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/common/GroupInfo.java
+++ b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/common/GroupInfo.java
@@ -25,6 +25,7 @@
   public Integer groupId;
   public String owner;
   public String ownerId;
+  public Boolean _moreGroups;
 
   // These fields are only supplied for internal groups, and only if requested.
   public List<AccountInfo> members;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/group/QueryGroups.java b/gerrit-server/src/main/java/com/google/gerrit/server/group/QueryGroups.java
index c0cab23..4252d35 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/group/QueryGroups.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/group/QueryGroups.java
@@ -27,6 +27,7 @@
 import com.google.gerrit.server.index.group.GroupIndex;
 import com.google.gerrit.server.index.group.GroupIndexCollection;
 import com.google.gerrit.server.query.QueryParseException;
+import com.google.gerrit.server.query.QueryResult;
 import com.google.gerrit.server.query.group.GroupQueryBuilder;
 import com.google.gerrit.server.query.group.GroupQueryProcessor;
 import com.google.gwtorm.server.OrmException;
@@ -110,15 +111,19 @@
     }
 
     try {
-      List<AccountGroup> result =
-          queryProcessor.query(queryBuilder.parse(query)).entities();
+      QueryResult<AccountGroup> result =
+          queryProcessor.query(queryBuilder.parse(query));
+      List<AccountGroup> groups = result.entities();
 
       ArrayList<GroupInfo> groupInfos =
-          Lists.newArrayListWithCapacity(result.size());
+          Lists.newArrayListWithCapacity(groups.size());
       json.addOptions(options);
-      for (AccountGroup group : result) {
+      for (AccountGroup group : groups) {
         groupInfos.add(json.format(GroupDescriptions.forAccountGroup(group)));
       }
+      if (!groupInfos.isEmpty() && result.more()) {
+        groupInfos.get(groupInfos.size() - 1)._moreGroups = true;
+      }
       return groupInfos;
     } catch (QueryParseException e) {
       throw new BadRequestException(e.getMessage());
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/query/group/AbstractQueryGroupsTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/query/group/AbstractQueryGroupsTest.java
index a15483d..59bc18d 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/query/group/AbstractQueryGroupsTest.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/query/group/AbstractQueryGroupsTest.java
@@ -193,8 +193,10 @@
     String query =
         "uuid:" + group1.id + " OR uuid:" + group2.id + " OR uuid:" + group3.id;
     List<GroupInfo> result = assertQuery(query, group1, group2, group3);
+    assertThat(result.get(result.size() - 1)._moreGroups).isNull();
 
-    assertQuery(newQuery(query).withLimit(2), result.subList(0, 2));
+    result = assertQuery(newQuery(query).withLimit(2), result.subList(0, 2));
+    assertThat(result.get(result.size() - 1)._moreGroups).isTrue();
   }
 
   @Test