Include label votes in ReviewerResource views
In addition to the account information, include all of the verbatim values as a map of label name to value. Refactor ReviewerJson to use the same AccountInfo.Loader mechanism as ChangeJson. This renames the "id" field to "_account_id" for consistency, and affects all reviewer resources requested. This compatibility break is ok as the old field was not documented or used. Example output from /changes/#/reviewers: [ { "kind": "gerritcodereview#reviewer", "approvals": { "Verified": "+1", "Code-Review": "+1" }, "_account_id": "1000000", "name": "User One", "email": "user1@gmail.com" }, { "kind": "gerritcodereview#reviewer", "approvals": { "Code-Review": " 0" }, "_account_id": "1000001", "name": "User Two", "email": "user2@gmail.com" } ] Change-Id: I78523800876d57772d6a5f22692d24e42b515a9a
This commit is contained in:

committed by
Edwin Kempin

parent
ee7ff53cbb
commit
f115ce78c7
@@ -77,7 +77,7 @@ class DeleteReviewer implements RestModifyView<ReviewerResource, Input> {
|
|||||||
new Predicate<PatchSetApproval>() {
|
new Predicate<PatchSetApproval>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(PatchSetApproval input) {
|
public boolean apply(PatchSetApproval input) {
|
||||||
return input.getAccountId().equals(rsrc.getAccount().getId());
|
return input.getAccountId().equals(rsrc.getUser().getAccountId());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -27,7 +27,7 @@ public class GetReviewer implements RestReadView<ReviewerResource> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object apply(ReviewerResource reviewerResource) throws OrmException {
|
public Object apply(ReviewerResource rsrc) throws OrmException {
|
||||||
return json.format(reviewerResource);
|
return json.format(rsrc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -32,20 +32,23 @@ class ListReviewers implements RestReadView<ChangeResource> {
|
|||||||
private final AccountCache accountCache;
|
private final AccountCache accountCache;
|
||||||
private final Provider<ReviewDb> dbProvider;
|
private final Provider<ReviewDb> dbProvider;
|
||||||
private final ReviewerJson json;
|
private final ReviewerJson json;
|
||||||
|
private final ReviewerResource.Factory resourceFactory;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ListReviewers(AccountCache accountCache,
|
ListReviewers(AccountCache accountCache,
|
||||||
Provider<ReviewDb> dbProvider,
|
Provider<ReviewDb> dbProvider,
|
||||||
|
ReviewerResource.Factory resourceFactory,
|
||||||
ReviewerJson json) {
|
ReviewerJson json) {
|
||||||
this.accountCache = accountCache;
|
this.accountCache = accountCache;
|
||||||
this.dbProvider = dbProvider;
|
this.dbProvider = dbProvider;
|
||||||
|
this.resourceFactory = resourceFactory;
|
||||||
this.json = json;
|
this.json = json;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object apply(ChangeResource rsrc) throws BadRequestException,
|
public Object apply(ChangeResource rsrc) throws BadRequestException,
|
||||||
OrmException {
|
OrmException {
|
||||||
Map<Account.Id, Object> reviewers = Maps.newLinkedHashMap();
|
Map<Account.Id, ReviewerResource> reviewers = Maps.newLinkedHashMap();
|
||||||
ReviewDb db = dbProvider.get();
|
ReviewDb db = dbProvider.get();
|
||||||
Change.Id changeId = rsrc.getChange().getId();
|
Change.Id changeId = rsrc.getChange().getId();
|
||||||
for (PatchSetApproval patchSetApproval
|
for (PatchSetApproval patchSetApproval
|
||||||
@@ -53,10 +56,9 @@ class ListReviewers implements RestReadView<ChangeResource> {
|
|||||||
Account.Id accountId = patchSetApproval.getAccountId();
|
Account.Id accountId = patchSetApproval.getAccountId();
|
||||||
if (!reviewers.containsKey(accountId)) {
|
if (!reviewers.containsKey(accountId)) {
|
||||||
Account account = accountCache.get(accountId).getAccount();
|
Account account = accountCache.get(accountId).getAccount();
|
||||||
reviewers.put(accountId,
|
reviewers.put(accountId, resourceFactory.create(rsrc, account));
|
||||||
json.format(new ReviewerResource(rsrc, account)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return reviewers.values();
|
return json.format(reviewers.values());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -71,6 +71,7 @@ public class Module extends RestApiModule {
|
|||||||
install(new FactoryModule() {
|
install(new FactoryModule() {
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
|
factory(ReviewerResource.Factory.class);
|
||||||
factory(AccountInfo.Loader.Factory.class);
|
factory(AccountInfo.Loader.Factory.class);
|
||||||
factory(EmailReviewComments.Factory.class);
|
factory(EmailReviewComments.Factory.class);
|
||||||
}
|
}
|
||||||
|
@@ -14,25 +14,104 @@
|
|||||||
|
|
||||||
package com.google.gerrit.server.change;
|
package com.google.gerrit.server.change;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.gerrit.common.data.ApprovalType;
|
||||||
|
import com.google.gerrit.common.data.ApprovalTypes;
|
||||||
|
import com.google.gerrit.common.data.PermissionRange;
|
||||||
import com.google.gerrit.reviewdb.client.Account;
|
import com.google.gerrit.reviewdb.client.Account;
|
||||||
|
import com.google.gerrit.reviewdb.client.ApprovalCategoryValue;
|
||||||
|
import com.google.gerrit.reviewdb.client.Change;
|
||||||
|
import com.google.gerrit.reviewdb.client.PatchSet;
|
||||||
|
import com.google.gerrit.reviewdb.client.PatchSetApproval;
|
||||||
|
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||||
|
import com.google.gerrit.server.project.ChangeControl;
|
||||||
|
import com.google.gerrit.server.workflow.CategoryFunction;
|
||||||
|
import com.google.gerrit.server.workflow.FunctionState;
|
||||||
|
import com.google.gwtorm.server.OrmException;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.Provider;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class ReviewerJson {
|
public class ReviewerJson {
|
||||||
ReviewerJson() {
|
private final Provider<ReviewDb> db;
|
||||||
|
private final ApprovalTypes approvalTypes;
|
||||||
|
private final FunctionState.Factory functionState;
|
||||||
|
private final AccountInfo.Loader.Factory accountLoaderFactory;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ReviewerJson(Provider<ReviewDb> db,
|
||||||
|
ApprovalTypes approvalTypes,
|
||||||
|
FunctionState.Factory functionState,
|
||||||
|
AccountInfo.Loader.Factory accountLoaderFactory) {
|
||||||
|
this.db = db;
|
||||||
|
this.approvalTypes = approvalTypes;
|
||||||
|
this.functionState = functionState;
|
||||||
|
this.accountLoaderFactory = accountLoaderFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReviewerInfo format(ReviewerResource reviewerResource) {
|
public List<ReviewerInfo> format(Collection<ReviewerResource> rsrcs) throws OrmException {
|
||||||
ReviewerInfo reviewerInfo = new ReviewerInfo();
|
List<ReviewerInfo> infos = Lists.newArrayListWithCapacity(rsrcs.size());
|
||||||
Account account = reviewerResource.getAccount();
|
AccountInfo.Loader loader = accountLoaderFactory.create(true);
|
||||||
reviewerInfo.id = account.getId().toString();
|
for (ReviewerResource rsrc : rsrcs) {
|
||||||
reviewerInfo.email = account.getPreferredEmail();
|
ReviewerInfo info = formatOne(rsrc);
|
||||||
reviewerInfo.name = account.getFullName();
|
loader.put(info);
|
||||||
return reviewerInfo;
|
infos.add(info);
|
||||||
|
}
|
||||||
|
loader.fill();
|
||||||
|
return infos;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ReviewerInfo {
|
public List<ReviewerInfo> format(ReviewerResource rsrc) throws OrmException {
|
||||||
|
return format(ImmutableList.<ReviewerResource> of(rsrc));
|
||||||
|
}
|
||||||
|
|
||||||
|
private ReviewerInfo formatOne(ReviewerResource rsrc) throws OrmException {
|
||||||
|
Account.Id id = rsrc.getUser().getAccountId();
|
||||||
|
ReviewerInfo out = new ReviewerInfo(id);
|
||||||
|
|
||||||
|
Change change = rsrc.getChange();
|
||||||
|
PatchSet.Id psId = change.currentPatchSetId();
|
||||||
|
|
||||||
|
List<PatchSetApproval> approvals = db.get().patchSetApprovals()
|
||||||
|
.byPatchSetUser(psId, id).toList();
|
||||||
|
|
||||||
|
ChangeControl control = rsrc.getControl().forUser(rsrc.getUser());
|
||||||
|
FunctionState fs = functionState.create(control, psId, approvals);
|
||||||
|
for (ApprovalType at : approvalTypes.getApprovalTypes()) {
|
||||||
|
CategoryFunction.forCategory(at.getCategory()).run(at, fs);
|
||||||
|
}
|
||||||
|
|
||||||
|
out.approvals = Maps.newHashMapWithExpectedSize(approvals.size());
|
||||||
|
for (PatchSetApproval ca : approvals) {
|
||||||
|
for (PermissionRange pr : control.getLabelRanges()) {
|
||||||
|
if (pr.getMin() != 0 || pr.getMax() != 0) {
|
||||||
|
// TODO: Support arbitrary labels.
|
||||||
|
ApprovalType at = approvalTypes.byId(ca.getCategoryId());
|
||||||
|
if (at != null) {
|
||||||
|
out.approvals.put(at.getCategory().getLabelName(),
|
||||||
|
ApprovalCategoryValue.formatValue(ca.getValue()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (out.approvals.isEmpty()) {
|
||||||
|
out.approvals = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ReviewerInfo extends AccountInfo {
|
||||||
final String kind = "gerritcodereview#reviewer";
|
final String kind = "gerritcodereview#reviewer";
|
||||||
String id;
|
Map<String, String> approvals;
|
||||||
String email;
|
|
||||||
String name;
|
protected ReviewerInfo(Account.Id id) {
|
||||||
|
super(id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,20 +16,37 @@ package com.google.gerrit.server.change;
|
|||||||
|
|
||||||
import com.google.gerrit.extensions.restapi.RestView;
|
import com.google.gerrit.extensions.restapi.RestView;
|
||||||
import com.google.gerrit.reviewdb.client.Account;
|
import com.google.gerrit.reviewdb.client.Account;
|
||||||
|
import com.google.gerrit.server.IdentifiedUser;
|
||||||
import com.google.inject.TypeLiteral;
|
import com.google.inject.TypeLiteral;
|
||||||
|
import com.google.inject.assistedinject.Assisted;
|
||||||
|
import com.google.inject.assistedinject.AssistedInject;
|
||||||
|
|
||||||
public class ReviewerResource extends ChangeResource {
|
public class ReviewerResource extends ChangeResource {
|
||||||
public static final TypeLiteral<RestView<ReviewerResource>> REVIEWER_KIND =
|
public static final TypeLiteral<RestView<ReviewerResource>> REVIEWER_KIND =
|
||||||
new TypeLiteral<RestView<ReviewerResource>>() {};
|
new TypeLiteral<RestView<ReviewerResource>>() {};
|
||||||
|
|
||||||
private final Account account;
|
static interface Factory {
|
||||||
|
ReviewerResource create(ChangeResource rsrc, IdentifiedUser user);
|
||||||
public ReviewerResource(ChangeResource changeResource, Account account) {
|
ReviewerResource create(ChangeResource rsrc, Account account);
|
||||||
super(changeResource);
|
|
||||||
this.account = account;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Account getAccount() {
|
private final IdentifiedUser user;
|
||||||
return account;
|
|
||||||
|
@AssistedInject
|
||||||
|
ReviewerResource(@Assisted ChangeResource rsrc,
|
||||||
|
@Assisted IdentifiedUser user) {
|
||||||
|
super(rsrc);
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
@AssistedInject
|
||||||
|
ReviewerResource(IdentifiedUser.GenericFactory userFactory,
|
||||||
|
@Assisted ChangeResource rsrc,
|
||||||
|
@Assisted Account account) {
|
||||||
|
this(rsrc, userFactory.create(account.getId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public IdentifiedUser getUser() {
|
||||||
|
return user;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -38,15 +38,18 @@ public class Reviewers implements
|
|||||||
ChildCollection<ChangeResource, ReviewerResource> {
|
ChildCollection<ChangeResource, ReviewerResource> {
|
||||||
private final DynamicMap<RestView<ReviewerResource>> views;
|
private final DynamicMap<RestView<ReviewerResource>> views;
|
||||||
private final Provider<ReviewDb> dbProvider;
|
private final Provider<ReviewDb> dbProvider;
|
||||||
|
private final ReviewerResource.Factory resourceFactory;
|
||||||
private final AccountCache accountCache;
|
private final AccountCache accountCache;
|
||||||
private final Provider<ListReviewers> list;
|
private final Provider<ListReviewers> list;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
Reviewers(Provider<ReviewDb> dbProvider,
|
Reviewers(Provider<ReviewDb> dbProvider,
|
||||||
DynamicMap<RestView<ReviewerResource>> views,
|
ReviewerResource.Factory resourceFactory,
|
||||||
AccountCache accountCache,
|
DynamicMap<RestView<ReviewerResource>> views,
|
||||||
Provider<ListReviewers> list) {
|
AccountCache accountCache,
|
||||||
|
Provider<ListReviewers> list) {
|
||||||
this.dbProvider = dbProvider;
|
this.dbProvider = dbProvider;
|
||||||
|
this.resourceFactory = resourceFactory;
|
||||||
this.views = views;
|
this.views = views;
|
||||||
this.accountCache = accountCache;
|
this.accountCache = accountCache;
|
||||||
this.list = list;
|
this.list = list;
|
||||||
@@ -69,7 +72,7 @@ public class Reviewers implements
|
|||||||
if (id.equals("self")) {
|
if (id.equals("self")) {
|
||||||
CurrentUser user = rsrc.getControl().getCurrentUser();
|
CurrentUser user = rsrc.getControl().getCurrentUser();
|
||||||
if (user instanceof IdentifiedUser) {
|
if (user instanceof IdentifiedUser) {
|
||||||
accountId = ((IdentifiedUser)user).getAccountId();
|
accountId = ((IdentifiedUser) user).getAccountId();
|
||||||
} else if (user instanceof AnonymousUser) {
|
} else if (user instanceof AnonymousUser) {
|
||||||
throw new AuthException("Authentication required");
|
throw new AuthException("Authentication required");
|
||||||
} else {
|
} else {
|
||||||
@@ -84,7 +87,7 @@ public class Reviewers implements
|
|||||||
// See if the id exists as a reviewer for this change
|
// See if the id exists as a reviewer for this change
|
||||||
if (fetchAccountIds(rsrc).contains(accountId)) {
|
if (fetchAccountIds(rsrc).contains(accountId)) {
|
||||||
Account account = accountCache.get(accountId).getAccount();
|
Account account = accountCache.get(accountId).getAccount();
|
||||||
return new ReviewerResource(rsrc, account);
|
return resourceFactory.create(rsrc, account);
|
||||||
}
|
}
|
||||||
throw new ResourceNotFoundException(id);
|
throw new ResourceNotFoundException(id);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user