Changes API: Add methods to suggest reviewers
Change-Id: I8bdc52eeaa8336558fff2e3a0682f861bc9008b8
This commit is contained in:
committed by
David Pursehouse
parent
b32ae744de
commit
64a436d152
@@ -26,10 +26,10 @@ import com.google.gerrit.common.data.AccessSection;
|
|||||||
import com.google.gerrit.common.data.GlobalCapability;
|
import com.google.gerrit.common.data.GlobalCapability;
|
||||||
import com.google.gerrit.common.data.Permission;
|
import com.google.gerrit.common.data.Permission;
|
||||||
import com.google.gerrit.common.data.PermissionRule;
|
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.reviewdb.client.AccountGroup;
|
||||||
import com.google.gerrit.server.account.CreateGroupArgs;
|
import com.google.gerrit.server.account.CreateGroupArgs;
|
||||||
import com.google.gerrit.server.account.PerformCreateGroup;
|
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.MetaDataUpdate;
|
||||||
import com.google.gerrit.server.git.ProjectConfig;
|
import com.google.gerrit.server.git.ProjectConfig;
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|||||||
@@ -16,10 +16,12 @@ package com.google.gerrit.extensions.api.changes;
|
|||||||
|
|
||||||
import com.google.gerrit.extensions.common.ChangeInfo;
|
import com.google.gerrit.extensions.common.ChangeInfo;
|
||||||
import com.google.gerrit.extensions.common.ListChangesOption;
|
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.NotImplementedException;
|
||||||
import com.google.gerrit.extensions.restapi.RestApiException;
|
import com.google.gerrit.extensions.restapi.RestApiException;
|
||||||
|
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public interface ChangeApi {
|
public interface ChangeApi {
|
||||||
@@ -79,6 +81,9 @@ public interface ChangeApi {
|
|||||||
void addReviewer(AddReviewerInput in) throws RestApiException;
|
void addReviewer(AddReviewerInput in) throws RestApiException;
|
||||||
void addReviewer(String 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;
|
ChangeInfo get(EnumSet<ListChangesOption> options) throws RestApiException;
|
||||||
|
|
||||||
/** {@code get} with {@link ListChangesOption} set to all except CHECK. */
|
/** {@code get} with {@link ListChangesOption} set to all except CHECK. */
|
||||||
@@ -101,6 +106,31 @@ public interface ChangeApi {
|
|||||||
ChangeInfo check() throws RestApiException;
|
ChangeInfo check() throws RestApiException;
|
||||||
ChangeInfo check(FixInput fix) 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
|
* A default implementation which allows source compatibility
|
||||||
* when adding new methods to the interface.
|
* when adding new methods to the interface.
|
||||||
@@ -176,6 +206,16 @@ public interface ChangeApi {
|
|||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SuggestedReviewersRequest suggestReviewers() throws RestApiException {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SuggestedReviewersRequest suggestReviewers(String query) throws RestApiException {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChangeInfo get(EnumSet<ListChangesOption> options) throws RestApiException {
|
public ChangeInfo get(EnumSet<ListChangesOption> options) throws RestApiException {
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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.api.changes.RevisionApi;
|
||||||
import com.google.gerrit.extensions.common.ChangeInfo;
|
import com.google.gerrit.extensions.common.ChangeInfo;
|
||||||
import com.google.gerrit.extensions.common.ListChangesOption;
|
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.IdString;
|
||||||
import com.google.gerrit.extensions.restapi.RestApiException;
|
import com.google.gerrit.extensions.restapi.RestApiException;
|
||||||
import com.google.gerrit.server.change.Abandon;
|
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.Restore;
|
||||||
import com.google.gerrit.server.change.Revert;
|
import com.google.gerrit.server.change.Revert;
|
||||||
import com.google.gerrit.server.change.Revisions;
|
import com.google.gerrit.server.change.Revisions;
|
||||||
|
import com.google.gerrit.server.change.SuggestReviewers;
|
||||||
import com.google.gwtorm.server.OrmException;
|
import com.google.gwtorm.server.OrmException;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
@@ -47,6 +49,7 @@ import com.google.inject.assistedinject.Assisted;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
class ChangeApiImpl extends ChangeApi.NotImplemented implements ChangeApi {
|
class ChangeApiImpl extends ChangeApi.NotImplemented implements ChangeApi {
|
||||||
@@ -57,6 +60,7 @@ class ChangeApiImpl extends ChangeApi.NotImplemented implements ChangeApi {
|
|||||||
private final Changes changeApi;
|
private final Changes changeApi;
|
||||||
private final Revisions revisions;
|
private final Revisions revisions;
|
||||||
private final RevisionApiImpl.Factory revisionApi;
|
private final RevisionApiImpl.Factory revisionApi;
|
||||||
|
private final Provider<SuggestReviewers> suggestReviewers;
|
||||||
private final ChangeResource change;
|
private final ChangeResource change;
|
||||||
private final Abandon abandon;
|
private final Abandon abandon;
|
||||||
private final Revert revert;
|
private final Revert revert;
|
||||||
@@ -73,6 +77,7 @@ class ChangeApiImpl extends ChangeApi.NotImplemented implements ChangeApi {
|
|||||||
ChangeApiImpl(Changes changeApi,
|
ChangeApiImpl(Changes changeApi,
|
||||||
Revisions revisions,
|
Revisions revisions,
|
||||||
RevisionApiImpl.Factory revisionApi,
|
RevisionApiImpl.Factory revisionApi,
|
||||||
|
Provider<SuggestReviewers> suggestReviewers,
|
||||||
Abandon abandon,
|
Abandon abandon,
|
||||||
Revert revert,
|
Revert revert,
|
||||||
Restore restore,
|
Restore restore,
|
||||||
@@ -88,6 +93,7 @@ class ChangeApiImpl extends ChangeApi.NotImplemented implements ChangeApi {
|
|||||||
this.revert = revert;
|
this.revert = revert;
|
||||||
this.revisions = revisions;
|
this.revisions = revisions;
|
||||||
this.revisionApi = revisionApi;
|
this.revisionApi = revisionApi;
|
||||||
|
this.suggestReviewers = suggestReviewers;
|
||||||
this.abandon = abandon;
|
this.abandon = abandon;
|
||||||
this.restore = restore;
|
this.restore = restore;
|
||||||
this.getTopic = getTopic;
|
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
|
@Override
|
||||||
public ChangeInfo get(EnumSet<ListChangesOption> s)
|
public ChangeInfo get(EnumSet<ListChangesOption> s)
|
||||||
throws RestApiException {
|
throws RestApiException {
|
||||||
|
|||||||
@@ -14,12 +14,17 @@
|
|||||||
|
|
||||||
package com.google.gerrit.server.change;
|
package com.google.gerrit.server.change;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.MoreObjects;
|
import com.google.common.base.MoreObjects;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Lists;
|
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.data.GroupReference;
|
||||||
import com.google.gerrit.common.errors.NoSuchGroupException;
|
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.common.AccountInfo;
|
||||||
import com.google.gerrit.extensions.restapi.BadRequestException;
|
import com.google.gerrit.extensions.restapi.BadRequestException;
|
||||||
import com.google.gerrit.extensions.restapi.RestReadView;
|
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.GroupBackend;
|
||||||
import com.google.gerrit.server.account.GroupMembers;
|
import com.google.gerrit.server.account.GroupMembers;
|
||||||
import com.google.gerrit.server.config.GerritServerConfig;
|
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.NoSuchProjectException;
|
||||||
import com.google.gerrit.server.project.ProjectControl;
|
import com.google.gerrit.server.project.ProjectControl;
|
||||||
import com.google.gwtorm.server.OrmException;
|
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 String MAX_SUFFIX = "\u9fa5";
|
||||||
private static final int DEFAULT_MAX_SUGGESTED = 10;
|
private static final int DEFAULT_MAX_SUGGESTED = 10;
|
||||||
private static final int DEFAULT_MAX_MATCHES = 100;
|
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 AccountLoader accountLoader;
|
||||||
private final AccountControl accountControl;
|
private final AccountControl accountControl;
|
||||||
@@ -159,7 +177,9 @@ public class SuggestReviewers implements RestReadView<ChangeResource> {
|
|||||||
|
|
||||||
List<SuggestedReviewerInfo> reviewer = Lists.newArrayList();
|
List<SuggestedReviewerInfo> reviewer = Lists.newArrayList();
|
||||||
for (AccountInfo a : suggestedAccounts) {
|
for (AccountInfo a : suggestedAccounts) {
|
||||||
reviewer.add(new SuggestedReviewerInfo(a));
|
SuggestedReviewerInfo info = new SuggestedReviewerInfo();
|
||||||
|
info.account = a;
|
||||||
|
reviewer.add(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
Project p = rsrc.getControl().getProject();
|
Project p = rsrc.getControl().getProject();
|
||||||
@@ -169,11 +189,13 @@ public class SuggestReviewers implements RestReadView<ChangeResource> {
|
|||||||
GroupBaseInfo info = new GroupBaseInfo();
|
GroupBaseInfo info = new GroupBaseInfo();
|
||||||
info.id = Url.encode(g.getUUID().get());
|
info.id = Url.encode(g.getUUID().get());
|
||||||
info.name = g.getName();
|
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) {
|
if (reviewer.size() <= limit) {
|
||||||
return reviewer;
|
return reviewer;
|
||||||
} else {
|
} else {
|
||||||
@@ -342,29 +364,4 @@ public class SuggestReviewers implements RestReadView<ChangeResource> {
|
|||||||
|
|
||||||
return false;
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user