Changes API: Add methods to suggest reviewers

Change-Id: I8bdc52eeaa8336558fff2e3a0682f861bc9008b8
This commit is contained in:
Thomas Forrer
2014-09-12 20:25:54 -07:00
committed by David Pursehouse
parent b32ae744de
commit 64a436d152
6 changed files with 141 additions and 30 deletions

View File

@@ -26,10 +26,10 @@ import com.google.gerrit.common.data.AccessSection;
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;

View File

@@ -16,10 +16,12 @@ package com.google.gerrit.extensions.api.changes;
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 @@ public interface ChangeApi {
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 @@ public interface ChangeApi {
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.
@@ -176,6 +206,16 @@ public interface ChangeApi {
throw new NotImplementedException();
}
@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();

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -26,6 +26,7 @@ import com.google.gerrit.extensions.api.changes.RevertInput;
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.PutTopic;
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 com.google.inject.assistedinject.Assisted;
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 @@ class ChangeApiImpl extends ChangeApi.NotImplemented implements ChangeApi {
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 @@ class ChangeApiImpl extends ChangeApi.NotImplemented implements ChangeApi {
ChangeApiImpl(Changes changeApi,
Revisions revisions,
RevisionApiImpl.Factory revisionApi,
Provider<SuggestReviewers> suggestReviewers,
Abandon abandon,
Revert revert,
Restore restore,
@@ -88,6 +93,7 @@ class ChangeApiImpl extends ChangeApi.NotImplemented implements ChangeApi {
this.revert = revert;
this.revisions = revisions;
this.revisionApi = revisionApi;
this.suggestReviewers = suggestReviewers;
this.abandon = abandon;
this.restore = restore;
this.getTopic = getTopic;
@@ -199,6 +205,34 @@ class ChangeApiImpl extends ChangeApi.NotImplemented implements ChangeApi {
}
}
@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 {

View File

@@ -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.AccountVisibility;
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 @@ public class SuggestReviewers implements RestReadView<ChangeResource> {
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 @@ public class SuggestReviewers implements RestReadView<ChangeResource> {
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 @@ public class SuggestReviewers implements RestReadView<ChangeResource> {
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 @@ public class SuggestReviewers implements RestReadView<ChangeResource> {
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);
}
}
}