Changes API: Add methods to suggest reviewers Change-Id: I8bdc52eeaa8336558fff2e3a0682f861bc9008b8
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/SuggestReviewersIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/SuggestReviewersIT.java index 15ada4a..ec1e299 100644 --- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/SuggestReviewersIT.java +++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/SuggestReviewersIT.java
@@ -26,10 +26,10 @@ import com.google.gerrit.common.data.GlobalCapability; import com.google.gerrit.common.data.Permission; import com.google.gerrit.common.data.PermissionRule; +import com.google.gerrit.extensions.common.SuggestedReviewerInfo; import com.google.gerrit.reviewdb.client.AccountGroup; import com.google.gerrit.server.account.CreateGroupArgs; import com.google.gerrit.server.account.PerformCreateGroup; -import com.google.gerrit.server.change.SuggestReviewers.SuggestedReviewerInfo; import com.google.gerrit.server.git.MetaDataUpdate; import com.google.gerrit.server.git.ProjectConfig; import com.google.gson.reflect.TypeToken;
diff --git a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/changes/ChangeApi.java b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/changes/ChangeApi.java index 78c95b9..bcf78b3 100644 --- a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/changes/ChangeApi.java +++ b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/changes/ChangeApi.java
@@ -16,10 +16,12 @@ import com.google.gerrit.extensions.common.ChangeInfo; import com.google.gerrit.extensions.common.ListChangesOption; +import com.google.gerrit.extensions.common.SuggestedReviewerInfo; import com.google.gerrit.extensions.restapi.NotImplementedException; import com.google.gerrit.extensions.restapi.RestApiException; import java.util.EnumSet; +import java.util.List; import java.util.Set; public interface ChangeApi { @@ -79,6 +81,9 @@ void addReviewer(AddReviewerInput in) throws RestApiException; void addReviewer(String in) throws RestApiException; + SuggestedReviewersRequest suggestReviewers() throws RestApiException; + SuggestedReviewersRequest suggestReviewers(String query) throws RestApiException; + ChangeInfo get(EnumSet<ListChangesOption> options) throws RestApiException; /** {@code get} with {@link ListChangesOption} set to all except CHECK. */ @@ -101,6 +106,31 @@ ChangeInfo check() throws RestApiException; ChangeInfo check(FixInput fix) throws RestApiException; + public abstract class SuggestedReviewersRequest { + private String query; + private int limit; + + public abstract List<SuggestedReviewerInfo> get() throws RestApiException; + + public SuggestedReviewersRequest withQuery(String query) { + this.query = query; + return this; + } + + public SuggestedReviewersRequest withLimit(int limit) { + this.limit = limit; + return this; + } + + public String getQuery() { + return query; + } + + public int getLimit() { + return limit; + } + } + /** * A default implementation which allows source compatibility * when adding new methods to the interface. @@ -177,6 +207,16 @@ } @Override + public SuggestedReviewersRequest suggestReviewers() throws RestApiException { + throw new NotImplementedException(); + } + + @Override + public SuggestedReviewersRequest suggestReviewers(String query) throws RestApiException { + throw new NotImplementedException(); + } + + @Override public ChangeInfo get(EnumSet<ListChangesOption> options) throws RestApiException { throw new NotImplementedException(); }
diff --git a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/common/GroupBaseInfo.java b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/common/GroupBaseInfo.java new file mode 100644 index 0000000..288adb6 --- /dev/null +++ b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/common/GroupBaseInfo.java
@@ -0,0 +1,20 @@ +// Copyright (C) 2014 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.gerrit.extensions.common; + +public class GroupBaseInfo { + public String id; + public String name; +}
diff --git a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/common/SuggestedReviewerInfo.java b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/common/SuggestedReviewerInfo.java new file mode 100644 index 0000000..d371f35 --- /dev/null +++ b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/common/SuggestedReviewerInfo.java
@@ -0,0 +1,20 @@ +// Copyright (C) 2014 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.gerrit.extensions.common; + +public class SuggestedReviewerInfo { + public AccountInfo account; + public GroupBaseInfo group; +}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/ChangeApiImpl.java b/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/ChangeApiImpl.java index 9dcf97b..e2d4a92 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/ChangeApiImpl.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/ChangeApiImpl.java
@@ -26,6 +26,7 @@ import com.google.gerrit.extensions.api.changes.RevisionApi; import com.google.gerrit.extensions.common.ChangeInfo; import com.google.gerrit.extensions.common.ListChangesOption; +import com.google.gerrit.extensions.common.SuggestedReviewerInfo; import com.google.gerrit.extensions.restapi.IdString; import com.google.gerrit.extensions.restapi.RestApiException; import com.google.gerrit.server.change.Abandon; @@ -40,6 +41,7 @@ import com.google.gerrit.server.change.Restore; import com.google.gerrit.server.change.Revert; import com.google.gerrit.server.change.Revisions; +import com.google.gerrit.server.change.SuggestReviewers; import com.google.gwtorm.server.OrmException; import com.google.inject.Inject; import com.google.inject.Provider; @@ -47,6 +49,7 @@ import java.io.IOException; import java.util.EnumSet; +import java.util.List; import java.util.Set; class ChangeApiImpl extends ChangeApi.NotImplemented implements ChangeApi { @@ -57,6 +60,7 @@ private final Changes changeApi; private final Revisions revisions; private final RevisionApiImpl.Factory revisionApi; + private final Provider<SuggestReviewers> suggestReviewers; private final ChangeResource change; private final Abandon abandon; private final Revert revert; @@ -73,6 +77,7 @@ ChangeApiImpl(Changes changeApi, Revisions revisions, RevisionApiImpl.Factory revisionApi, + Provider<SuggestReviewers> suggestReviewers, Abandon abandon, Revert revert, Restore restore, @@ -88,6 +93,7 @@ this.revert = revert; this.revisions = revisions; this.revisionApi = revisionApi; + this.suggestReviewers = suggestReviewers; this.abandon = abandon; this.restore = restore; this.getTopic = getTopic; @@ -200,6 +206,34 @@ } @Override + public SuggestedReviewersRequest suggestReviewers() throws RestApiException { + return new SuggestedReviewersRequest() { + @Override + public List<SuggestedReviewerInfo> get() throws RestApiException { + return ChangeApiImpl.this.suggestReviewers(this); + } + }; + } + + @Override + public SuggestedReviewersRequest suggestReviewers(String query) + throws RestApiException { + return suggestReviewers().withQuery(query); + } + + private List<SuggestedReviewerInfo> suggestReviewers(SuggestedReviewersRequest r) + throws RestApiException { + try { + SuggestReviewers mySuggestReviewers = suggestReviewers.get(); + mySuggestReviewers.setQuery(r.getQuery()); + mySuggestReviewers.setLimit(r.getLimit()); + return mySuggestReviewers.apply(change); + } catch (OrmException | IOException e) { + throw new RestApiException("Cannot retrieve suggested reviewers", e); + } + } + + @Override public ChangeInfo get(EnumSet<ListChangesOption> s) throws RestApiException { try {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/SuggestReviewers.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/SuggestReviewers.java index ce22034..5998eb1 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/change/SuggestReviewers.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/SuggestReviewers.java
@@ -14,12 +14,17 @@ package com.google.gerrit.server.change; +import com.google.common.base.Function; import com.google.common.base.MoreObjects; import com.google.common.base.Strings; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; +import com.google.common.collect.Ordering; +import com.google.gerrit.common.Nullable; import com.google.gerrit.common.data.GroupReference; import com.google.gerrit.common.errors.NoSuchGroupException; +import com.google.gerrit.extensions.common.GroupBaseInfo; +import com.google.gerrit.extensions.common.SuggestedReviewerInfo; import com.google.gerrit.extensions.common.AccountInfo; import com.google.gerrit.extensions.restapi.BadRequestException; import com.google.gerrit.extensions.restapi.RestReadView; @@ -37,7 +42,6 @@ import com.google.gerrit.server.account.GroupBackend; import com.google.gerrit.server.account.GroupMembers; import com.google.gerrit.server.config.GerritServerConfig; -import com.google.gerrit.server.group.GroupJson.GroupBaseInfo; import com.google.gerrit.server.project.NoSuchProjectException; import com.google.gerrit.server.project.ProjectControl; import com.google.gwtorm.server.OrmException; @@ -60,6 +64,20 @@ private static final String MAX_SUFFIX = "\u9fa5"; private static final int DEFAULT_MAX_SUGGESTED = 10; private static final int DEFAULT_MAX_MATCHES = 100; + private static final Ordering<SuggestedReviewerInfo> ORDERING = + Ordering.natural().onResultOf(new Function<SuggestedReviewerInfo, String>() { + @Nullable + @Override + public String apply(@Nullable SuggestedReviewerInfo suggestedReviewerInfo) { + if (suggestedReviewerInfo == null) { + return null; + } + return suggestedReviewerInfo.account != null + ? MoreObjects.firstNonNull(suggestedReviewerInfo.account.email, + Strings.nullToEmpty(suggestedReviewerInfo.account.name)) + : Strings.nullToEmpty(suggestedReviewerInfo.group.name); + } + }); private final AccountLoader accountLoader; private final AccountControl accountControl; @@ -159,7 +177,9 @@ List<SuggestedReviewerInfo> reviewer = Lists.newArrayList(); for (AccountInfo a : suggestedAccounts) { - reviewer.add(new SuggestedReviewerInfo(a)); + SuggestedReviewerInfo info = new SuggestedReviewerInfo(); + info.account = a; + reviewer.add(info); } Project p = rsrc.getControl().getProject(); @@ -169,11 +189,13 @@ GroupBaseInfo info = new GroupBaseInfo(); info.id = Url.encode(g.getUUID().get()); info.name = g.getName(); - reviewer.add(new SuggestedReviewerInfo(info)); + SuggestedReviewerInfo suggestedReviewerInfo = new SuggestedReviewerInfo(); + suggestedReviewerInfo.group = info; + reviewer.add(suggestedReviewerInfo); } } - Collections.sort(reviewer); + reviewer = ORDERING.immutableSortedCopy(reviewer); if (reviewer.size() <= limit) { return reviewer; } else { @@ -342,29 +364,4 @@ return false; } - - public static class SuggestedReviewerInfo implements Comparable<SuggestedReviewerInfo> { - public AccountInfo account; - public GroupBaseInfo group; - - SuggestedReviewerInfo(AccountInfo a) { - this.account = a; - } - - SuggestedReviewerInfo(GroupBaseInfo g) { - this.group = g; - } - - @Override - public int compareTo(SuggestedReviewerInfo o) { - return getSortValue().compareTo(o.getSortValue()); - } - - private String getSortValue() { - return account != null - ? MoreObjects.firstNonNull(account.email, - Strings.nullToEmpty(account.name)) - : Strings.nullToEmpty(group.name); - } - } }