Move ChangeControl#getLabelTypes() to ProjectState and migrate callers

In an effort to make {Ref,Project,Change}Control package-private all
public methods that aren't replaced by PermissionBackend need to move
elsewhere. Both ProjectControl#getLabelTypes() and
ChangeControl#getLabelTypes() rely on the project state, so they
can move there. ChangeControl#getLabelTypes() needs the destination
branch and current user in addition, which are added as arguments.

Change-Id: I080fd93103679552952872dde49cc149a59cd43e
This commit is contained in:
Patrick Hiesel
2017-08-30 10:12:37 +02:00
parent 31862df733
commit ed5ce1722f
17 changed files with 194 additions and 122 deletions

View File

@@ -221,7 +221,7 @@ class ProjectAccessFactory extends Handler<ProjectAccess> {
|| (checkReadConfig && perm.ref(RefNames.REFS_CONFIG).testOrFalse(CREATE_CHANGE))); || (checkReadConfig && perm.ref(RefNames.REFS_CONFIG).testOrFalse(CREATE_CHANGE)));
detail.setConfigVisible(pc.isOwner() || checkReadConfig); detail.setConfigVisible(pc.isOwner() || checkReadConfig);
detail.setGroupInfo(buildGroupInfo(local)); detail.setGroupInfo(buildGroupInfo(local));
detail.setLabelTypes(pc.getLabelTypes()); detail.setLabelTypes(pc.getProjectState().getLabelTypes());
detail.setFileHistoryLinks(getConfigFileLogLinks(projectName.get())); detail.setFileHistoryLinks(getConfigFileLogLinks(projectName.get()));
return detail; return detail;
} }

View File

@@ -94,7 +94,6 @@ public class ChangeInserter implements InsertChangeOp {
private final PermissionBackend permissionBackend; private final PermissionBackend permissionBackend;
private final ProjectCache projectCache; private final ProjectCache projectCache;
private final IdentifiedUser.GenericFactory userFactory; private final IdentifiedUser.GenericFactory userFactory;
private final ChangeControl.GenericFactory changeControlFactory;
private final PatchSetInfoFactory patchSetInfoFactory; private final PatchSetInfoFactory patchSetInfoFactory;
private final PatchSetUtil psUtil; private final PatchSetUtil psUtil;
private final ApprovalsUtil approvalsUtil; private final ApprovalsUtil approvalsUtil;
@@ -144,7 +143,6 @@ public class ChangeInserter implements InsertChangeOp {
PermissionBackend permissionBackend, PermissionBackend permissionBackend,
ProjectCache projectCache, ProjectCache projectCache,
IdentifiedUser.GenericFactory userFactory, IdentifiedUser.GenericFactory userFactory,
ChangeControl.GenericFactory changeControlFactory,
PatchSetInfoFactory patchSetInfoFactory, PatchSetInfoFactory patchSetInfoFactory,
PatchSetUtil psUtil, PatchSetUtil psUtil,
ApprovalsUtil approvalsUtil, ApprovalsUtil approvalsUtil,
@@ -161,7 +159,6 @@ public class ChangeInserter implements InsertChangeOp {
this.permissionBackend = permissionBackend; this.permissionBackend = permissionBackend;
this.projectCache = projectCache; this.projectCache = projectCache;
this.userFactory = userFactory; this.userFactory = userFactory;
this.changeControlFactory = changeControlFactory;
this.patchSetInfoFactory = patchSetInfoFactory; this.patchSetInfoFactory = patchSetInfoFactory;
this.psUtil = psUtil; this.psUtil = psUtil;
this.approvalsUtil = approvalsUtil; this.approvalsUtil = approvalsUtil;
@@ -436,7 +433,7 @@ public class ChangeInserter implements InsertChangeOp {
reviewersToAdd.addAll(extraCC); reviewersToAdd.addAll(extraCC);
} }
LabelTypes labelTypes = ctl.getProjectControl().getLabelTypes(); LabelTypes labelTypes = ctl.getProjectControl().getProjectState().getLabelTypes();
approvalsUtil.addReviewers( approvalsUtil.addReviewers(
db, db,
update, update,
@@ -493,7 +490,7 @@ public class ChangeInserter implements InsertChangeOp {
} }
@Override @Override
public void postUpdate(Context ctx) throws OrmException { public void postUpdate(Context ctx) throws OrmException, IOException {
if (sendMail && (notify != NotifyHandling.NONE || !accountsToNotify.isEmpty())) { if (sendMail && (notify != NotifyHandling.NONE || !accountsToNotify.isEmpty())) {
Runnable sender = Runnable sender =
new Runnable() { new Runnable() {
@@ -536,9 +533,11 @@ public class ChangeInserter implements InsertChangeOp {
if (fireRevisionCreated) { if (fireRevisionCreated) {
revisionCreated.fire(change, patchSet, ctx.getAccount(), ctx.getWhen(), notify); revisionCreated.fire(change, patchSet, ctx.getAccount(), ctx.getWhen(), notify);
if (approvals != null && !approvals.isEmpty()) { if (approvals != null && !approvals.isEmpty()) {
ChangeControl changeControl = List<LabelType> labels =
changeControlFactory.controlFor(ctx.getDb(), change, ctx.getUser()); projectCache
List<LabelType> labels = changeControl.getLabelTypes().getLabelTypes(); .checkedGet(ctx.getProject())
.getLabelTypes(change.getDest(), ctx.getUser())
.getLabelTypes();
Map<String, Short> allApprovals = new HashMap<>(); Map<String, Short> allApprovals = new HashMap<>();
Map<String, Short> oldApprovals = new HashMap<>(); Map<String, Short> oldApprovals = new HashMap<>();
for (LabelType lt : labels) { for (LabelType lt : labels) {

View File

@@ -39,6 +39,7 @@ import com.google.gerrit.server.notedb.ChangeUpdate;
import com.google.gerrit.server.notedb.NoteDbChangeState.PrimaryStorage; import com.google.gerrit.server.notedb.NoteDbChangeState.PrimaryStorage;
import com.google.gerrit.server.notedb.NotesMigration; import com.google.gerrit.server.notedb.NotesMigration;
import com.google.gerrit.server.permissions.PermissionBackendException; import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.RemoveReviewerControl; import com.google.gerrit.server.project.RemoveReviewerControl;
import com.google.gerrit.server.update.BatchUpdateOp; import com.google.gerrit.server.update.BatchUpdateOp;
import com.google.gerrit.server.update.BatchUpdateReviewDb; import com.google.gerrit.server.update.BatchUpdateReviewDb;
@@ -48,6 +49,7 @@ 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;
import com.google.inject.assistedinject.Assisted; import com.google.inject.assistedinject.Assisted;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@@ -73,6 +75,7 @@ public class DeleteReviewerOp implements BatchUpdateOp {
private final NotesMigration migration; private final NotesMigration migration;
private final NotifyUtil notifyUtil; private final NotifyUtil notifyUtil;
private final RemoveReviewerControl removeReviewerControl; private final RemoveReviewerControl removeReviewerControl;
private final ProjectCache projectCache;
private final Account reviewer; private final Account reviewer;
private final DeleteReviewerInput input; private final DeleteReviewerInput input;
@@ -95,6 +98,7 @@ public class DeleteReviewerOp implements BatchUpdateOp {
NotesMigration migration, NotesMigration migration,
NotifyUtil notifyUtil, NotifyUtil notifyUtil,
RemoveReviewerControl removeReviewerControl, RemoveReviewerControl removeReviewerControl,
ProjectCache projectCache,
@Assisted Account reviewerAccount, @Assisted Account reviewerAccount,
@Assisted DeleteReviewerInput input) { @Assisted DeleteReviewerInput input) {
this.approvalsUtil = approvalsUtil; this.approvalsUtil = approvalsUtil;
@@ -107,14 +111,15 @@ public class DeleteReviewerOp implements BatchUpdateOp {
this.migration = migration; this.migration = migration;
this.notifyUtil = notifyUtil; this.notifyUtil = notifyUtil;
this.removeReviewerControl = removeReviewerControl; this.removeReviewerControl = removeReviewerControl;
this.projectCache = projectCache;
this.reviewer = reviewerAccount; this.reviewer = reviewerAccount;
this.input = input; this.input = input;
} }
@Override @Override
public boolean updateChange(ChangeContext ctx) public boolean updateChange(ChangeContext ctx)
throws AuthException, ResourceNotFoundException, OrmException, PermissionBackendException { throws AuthException, ResourceNotFoundException, OrmException, PermissionBackendException,
IOException {
Account.Id reviewerId = reviewer.getId(); Account.Id reviewerId = reviewer.getId();
if (!approvalsUtil.getReviewers(ctx.getDb(), ctx.getNotes()).all().contains(reviewerId)) { if (!approvalsUtil.getReviewers(ctx.getDb(), ctx.getNotes()).all().contains(reviewerId)) {
throw new ResourceNotFoundException(); throw new ResourceNotFoundException();
@@ -122,7 +127,8 @@ public class DeleteReviewerOp implements BatchUpdateOp {
currChange = ctx.getChange(); currChange = ctx.getChange();
currPs = psUtil.current(ctx.getDb(), ctx.getNotes()); currPs = psUtil.current(ctx.getDb(), ctx.getNotes());
LabelTypes labelTypes = ctx.getControl().getLabelTypes(); LabelTypes labelTypes =
projectCache.checkedGet(ctx.getProject()).getLabelTypes(ctx.getNotes(), ctx.getUser());
// removing a reviewer will remove all her votes // removing a reviewer will remove all her votes
for (LabelType lt : labelTypes.getLabelTypes()) { for (LabelType lt : labelTypes.getLabelTypes()) {
newApprovals.put(lt.getName(), (short) 0); newApprovals.put(lt.getName(), (short) 0);

View File

@@ -42,6 +42,8 @@ import com.google.gerrit.server.mail.send.DeleteVoteSender;
import com.google.gerrit.server.mail.send.ReplyToChangeSender; import com.google.gerrit.server.mail.send.ReplyToChangeSender;
import com.google.gerrit.server.permissions.PermissionBackendException; import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.project.ChangeControl; import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.project.RemoveReviewerControl; import com.google.gerrit.server.project.RemoveReviewerControl;
import com.google.gerrit.server.update.BatchUpdate; import com.google.gerrit.server.update.BatchUpdate;
import com.google.gerrit.server.update.BatchUpdateOp; import com.google.gerrit.server.update.BatchUpdateOp;
@@ -75,6 +77,7 @@ public class DeleteVote extends RetryingRestModifyView<VoteResource, DeleteVoteI
private final DeleteVoteSender.Factory deleteVoteSenderFactory; private final DeleteVoteSender.Factory deleteVoteSenderFactory;
private final NotifyUtil notifyUtil; private final NotifyUtil notifyUtil;
private final RemoveReviewerControl removeReviewerControl; private final RemoveReviewerControl removeReviewerControl;
private final ProjectCache projectCache;
@Inject @Inject
DeleteVote( DeleteVote(
@@ -87,7 +90,8 @@ public class DeleteVote extends RetryingRestModifyView<VoteResource, DeleteVoteI
VoteDeleted voteDeleted, VoteDeleted voteDeleted,
DeleteVoteSender.Factory deleteVoteSenderFactory, DeleteVoteSender.Factory deleteVoteSenderFactory,
NotifyUtil notifyUtil, NotifyUtil notifyUtil,
RemoveReviewerControl removeReviewerControl) { RemoveReviewerControl removeReviewerControl,
ProjectCache projectCache) {
super(retryHelper); super(retryHelper);
this.db = db; this.db = db;
this.approvalsUtil = approvalsUtil; this.approvalsUtil = approvalsUtil;
@@ -98,12 +102,13 @@ public class DeleteVote extends RetryingRestModifyView<VoteResource, DeleteVoteI
this.deleteVoteSenderFactory = deleteVoteSenderFactory; this.deleteVoteSenderFactory = deleteVoteSenderFactory;
this.notifyUtil = notifyUtil; this.notifyUtil = notifyUtil;
this.removeReviewerControl = removeReviewerControl; this.removeReviewerControl = removeReviewerControl;
this.projectCache = projectCache;
} }
@Override @Override
protected Response<?> applyImpl( protected Response<?> applyImpl(
BatchUpdate.Factory updateFactory, VoteResource rsrc, DeleteVoteInput input) BatchUpdate.Factory updateFactory, VoteResource rsrc, DeleteVoteInput input)
throws RestApiException, UpdateException { throws RestApiException, UpdateException, IOException {
if (input == null) { if (input == null) {
input = new DeleteVoteInput(); input = new DeleteVoteInput();
} }
@@ -123,7 +128,13 @@ public class DeleteVote extends RetryingRestModifyView<VoteResource, DeleteVoteI
try (BatchUpdate bu = try (BatchUpdate bu =
updateFactory.create( updateFactory.create(
db.get(), change.getProject(), r.getControl().getUser(), TimeUtil.nowTs())) { db.get(), change.getProject(), r.getControl().getUser(), TimeUtil.nowTs())) {
bu.addOp(change.getId(), new Op(r.getReviewerUser().getAccount(), rsrc.getLabel(), input)); bu.addOp(
change.getId(),
new Op(
projectCache.checkedGet(r.getChange().getProject()),
r.getReviewerUser().getAccount(),
rsrc.getLabel(),
input));
bu.execute(); bu.execute();
} }
@@ -131,16 +142,19 @@ public class DeleteVote extends RetryingRestModifyView<VoteResource, DeleteVoteI
} }
private class Op implements BatchUpdateOp { private class Op implements BatchUpdateOp {
private final ProjectState projectState;
private final Account account; private final Account account;
private final String label; private final String label;
private final DeleteVoteInput input; private final DeleteVoteInput input;
private ChangeMessage changeMessage; private ChangeMessage changeMessage;
private Change change; private Change change;
private PatchSet ps; private PatchSet ps;
private Map<String, Short> newApprovals = new HashMap<>(); private Map<String, Short> newApprovals = new HashMap<>();
private Map<String, Short> oldApprovals = new HashMap<>(); private Map<String, Short> oldApprovals = new HashMap<>();
private Op(Account account, String label, DeleteVoteInput input) { private Op(ProjectState projectState, Account account, String label, DeleteVoteInput input) {
this.projectState = projectState;
this.account = account; this.account = account;
this.label = label; this.label = label;
this.input = input; this.input = input;
@@ -156,7 +170,7 @@ public class DeleteVote extends RetryingRestModifyView<VoteResource, DeleteVoteI
ps = psUtil.current(db.get(), ctl.getNotes()); ps = psUtil.current(db.get(), ctl.getNotes());
boolean found = false; boolean found = false;
LabelTypes labelTypes = ctx.getControl().getLabelTypes(); LabelTypes labelTypes = projectState.getLabelTypes(ctx.getNotes(), ctx.getUser());
for (PatchSetApproval a : for (PatchSetApproval a :
approvalsUtil.byPatchSetUser( approvalsUtil.byPatchSetUser(

View File

@@ -98,6 +98,8 @@ import com.google.gerrit.server.permissions.LabelPermission;
import com.google.gerrit.server.permissions.PermissionBackend; import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException; import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.project.ChangeControl; import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.query.change.ChangeData; import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.update.BatchUpdate; import com.google.gerrit.server.update.BatchUpdate;
import com.google.gerrit.server.update.BatchUpdateOp; import com.google.gerrit.server.update.BatchUpdateOp;
@@ -159,6 +161,7 @@ public class PostReview
private final NotifyUtil notifyUtil; private final NotifyUtil notifyUtil;
private final Config gerritConfig; private final Config gerritConfig;
private final WorkInProgressOp.Factory workInProgressOpFactory; private final WorkInProgressOp.Factory workInProgressOpFactory;
private final ProjectCache projectCache;
@Inject @Inject
PostReview( PostReview(
@@ -178,7 +181,8 @@ public class PostReview
NotesMigration migration, NotesMigration migration,
NotifyUtil notifyUtil, NotifyUtil notifyUtil,
@GerritServerConfig Config gerritConfig, @GerritServerConfig Config gerritConfig,
WorkInProgressOp.Factory workInProgressOpFactory) { WorkInProgressOp.Factory workInProgressOpFactory,
ProjectCache projectCache) {
super(retryHelper); super(retryHelper);
this.db = db; this.db = db;
this.changes = changes; this.changes = changes;
@@ -196,6 +200,7 @@ public class PostReview
this.notifyUtil = notifyUtil; this.notifyUtil = notifyUtil;
this.gerritConfig = gerritConfig; this.gerritConfig = gerritConfig;
this.workInProgressOpFactory = workInProgressOpFactory; this.workInProgressOpFactory = workInProgressOpFactory;
this.projectCache = projectCache;
} }
@Override @Override
@@ -215,13 +220,15 @@ public class PostReview
if (revision.getEdit().isPresent()) { if (revision.getEdit().isPresent()) {
throw new ResourceConflictException("cannot post review on edit"); throw new ResourceConflictException("cannot post review on edit");
} }
ProjectState projectState = projectCache.checkedGet(revision.getProject());
LabelTypes labelTypes = projectState.getLabelTypes(revision.getNotes(), revision.getUser());
if (input.onBehalfOf != null) { if (input.onBehalfOf != null) {
revision = onBehalfOf(revision, input); revision = onBehalfOf(revision, labelTypes, input);
} else if (input.drafts == null) { } else if (input.drafts == null) {
input.drafts = DraftHandling.DELETE; input.drafts = DraftHandling.DELETE;
} }
if (input.labels != null) { if (input.labels != null) {
checkLabels(revision, input.strictLabels, input.labels); checkLabels(revision, labelTypes, input.strictLabels, input.labels);
} }
if (input.comments != null) { if (input.comments != null) {
cleanUpComments(input.comments); cleanUpComments(input.comments);
@@ -348,7 +355,7 @@ public class PostReview
// Add the review op. // Add the review op.
bu.addOp( bu.addOp(
revision.getChange().getId(), revision.getChange().getId(),
new Op(revision.getPatchSet().getId(), input, accountsToNotify)); new Op(projectState, revision.getPatchSet().getId(), input, accountsToNotify));
bu.execute(); bu.execute();
@@ -411,7 +418,7 @@ public class PostReview
} }
} }
private RevisionResource onBehalfOf(RevisionResource rev, ReviewInput in) private RevisionResource onBehalfOf(RevisionResource rev, LabelTypes labelTypes, ReviewInput in)
throws BadRequestException, AuthException, UnprocessableEntityException, OrmException, throws BadRequestException, AuthException, UnprocessableEntityException, OrmException,
PermissionBackendException, IOException, ConfigInvalidException { PermissionBackendException, IOException, ConfigInvalidException {
if (in.labels == null || in.labels.isEmpty()) { if (in.labels == null || in.labels.isEmpty()) {
@@ -427,7 +434,6 @@ public class PostReview
CurrentUser caller = rev.getUser(); CurrentUser caller = rev.getUser();
PermissionBackend.ForChange perm = rev.permissions().database(db); PermissionBackend.ForChange perm = rev.permissions().database(db);
LabelTypes labelTypes = rev.getControl().getLabelTypes();
Iterator<Map.Entry<String, Short>> itr = in.labels.entrySet().iterator(); Iterator<Map.Entry<String, Short>> itr = in.labels.entrySet().iterator();
while (itr.hasNext()) { while (itr.hasNext()) {
Map.Entry<String, Short> ent = itr.next(); Map.Entry<String, Short> ent = itr.next();
@@ -468,14 +474,14 @@ public class PostReview
return new RevisionResource(changes.parse(ctl), rev.getPatchSet()); return new RevisionResource(changes.parse(ctl), rev.getPatchSet());
} }
private void checkLabels(RevisionResource rsrc, boolean strict, Map<String, Short> labels) private void checkLabels(
RevisionResource rsrc, LabelTypes labelTypes, boolean strict, Map<String, Short> labels)
throws BadRequestException, AuthException, PermissionBackendException { throws BadRequestException, AuthException, PermissionBackendException {
LabelTypes types = rsrc.getControl().getLabelTypes();
PermissionBackend.ForChange perm = rsrc.permissions(); PermissionBackend.ForChange perm = rsrc.permissions();
Iterator<Map.Entry<String, Short>> itr = labels.entrySet().iterator(); Iterator<Map.Entry<String, Short>> itr = labels.entrySet().iterator();
while (itr.hasNext()) { while (itr.hasNext()) {
Map.Entry<String, Short> ent = itr.next(); Map.Entry<String, Short> ent = itr.next();
LabelType lt = types.byLabel(ent.getKey()); LabelType lt = labelTypes.byLabel(ent.getKey());
if (lt == null) { if (lt == null) {
if (strict) { if (strict) {
throw new BadRequestException( throw new BadRequestException(
@@ -810,6 +816,7 @@ public class PostReview
} }
private class Op implements BatchUpdateOp { private class Op implements BatchUpdateOp {
private final ProjectState projectState;
private final PatchSet.Id psId; private final PatchSet.Id psId;
private final ReviewInput in; private final ReviewInput in;
private final ListMultimap<RecipientType, Account.Id> accountsToNotify; private final ListMultimap<RecipientType, Account.Id> accountsToNotify;
@@ -824,9 +831,11 @@ public class PostReview
private Map<String, Short> oldApprovals = new HashMap<>(); private Map<String, Short> oldApprovals = new HashMap<>();
private Op( private Op(
ProjectState projectState,
PatchSet.Id psId, PatchSet.Id psId,
ReviewInput in, ReviewInput in,
ListMultimap<RecipientType, Account.Id> accountsToNotify) { ListMultimap<RecipientType, Account.Id> accountsToNotify) {
this.projectState = projectState;
this.psId = psId; this.psId = psId;
this.in = in; this.in = in;
this.accountsToNotify = checkNotNull(accountsToNotify); this.accountsToNotify = checkNotNull(accountsToNotify);
@@ -841,7 +850,7 @@ public class PostReview
boolean dirty = false; boolean dirty = false;
dirty |= insertComments(ctx); dirty |= insertComments(ctx);
dirty |= insertRobotComments(ctx); dirty |= insertRobotComments(ctx);
dirty |= updateLabels(ctx); dirty |= updateLabels(projectState, ctx);
dirty |= insertMessage(ctx); dirty |= insertMessage(ctx);
return dirty; return dirty;
} }
@@ -1107,7 +1116,7 @@ public class PostReview
return false; return false;
} }
private boolean updateLabels(ChangeContext ctx) private boolean updateLabels(ProjectState projectState, ChangeContext ctx)
throws OrmException, ResourceConflictException, IOException { throws OrmException, ResourceConflictException, IOException {
Map<String, Short> inLabels = Map<String, Short> inLabels =
MoreObjects.firstNonNull(in.labels, Collections.<String, Short>emptyMap()); MoreObjects.firstNonNull(in.labels, Collections.<String, Short>emptyMap());
@@ -1121,8 +1130,8 @@ public class PostReview
List<PatchSetApproval> del = new ArrayList<>(); List<PatchSetApproval> del = new ArrayList<>();
List<PatchSetApproval> ups = new ArrayList<>(); List<PatchSetApproval> ups = new ArrayList<>();
Map<String, PatchSetApproval> current = scanLabels(ctx, del); Map<String, PatchSetApproval> current = scanLabels(projectState, ctx, del);
LabelTypes labelTypes = ctx.getControl().getLabelTypes(); LabelTypes labelTypes = projectState.getLabelTypes(ctx.getNotes(), ctx.getUser());
Map<String, Short> allApprovals = Map<String, Short> allApprovals =
getAllApprovals(labelTypes, approvalsByKey(current.values()), inLabels); getAllApprovals(labelTypes, approvalsByKey(current.values()), inLabels);
Map<String, Short> previous = Map<String, Short> previous =
@@ -1182,7 +1191,7 @@ public class PostReview
return false; return false;
} }
forceCallerAsReviewer(ctx, current, ups, del); forceCallerAsReviewer(projectState, ctx, current, ups, del);
ctx.getDb().patchSetApprovals().delete(del); ctx.getDb().patchSetApprovals().delete(del);
ctx.getDb().patchSetApprovals().upsert(ups); ctx.getDb().patchSetApprovals().upsert(ups);
return !del.isEmpty() || !ups.isEmpty(); return !del.isEmpty() || !ups.isEmpty();
@@ -1260,6 +1269,7 @@ public class PostReview
} }
private void forceCallerAsReviewer( private void forceCallerAsReviewer(
ProjectState projectState,
ChangeContext ctx, ChangeContext ctx,
Map<String, PatchSetApproval> current, Map<String, PatchSetApproval> current,
List<PatchSetApproval> ups, List<PatchSetApproval> ups,
@@ -1269,7 +1279,12 @@ public class PostReview
if (del.isEmpty()) { if (del.isEmpty()) {
// If no existing label is being set to 0, hack in the caller // If no existing label is being set to 0, hack in the caller
// as a reviewer by picking the first server-wide LabelType. // as a reviewer by picking the first server-wide LabelType.
LabelId labelId = ctx.getControl().getLabelTypes().getLabelTypes().get(0).getLabelId(); LabelId labelId =
projectState
.getLabelTypes(ctx.getNotes(), ctx.getUser())
.getLabelTypes()
.get(0)
.getLabelId();
PatchSetApproval c = ApprovalsUtil.newApproval(psId, user, labelId, 0, ctx.getWhen()); PatchSetApproval c = ApprovalsUtil.newApproval(psId, user, labelId, 0, ctx.getWhen());
c.setTag(in.tag); c.setTag(in.tag);
c.setGranted(ctx.getWhen()); c.setGranted(ctx.getWhen());
@@ -1287,9 +1302,10 @@ public class PostReview
ctx.getUpdate(ctx.getChange().currentPatchSetId()).putReviewer(user.getAccountId(), REVIEWER); ctx.getUpdate(ctx.getChange().currentPatchSetId()).putReviewer(user.getAccountId(), REVIEWER);
} }
private Map<String, PatchSetApproval> scanLabels(ChangeContext ctx, List<PatchSetApproval> del) private Map<String, PatchSetApproval> scanLabels(
ProjectState projectState, ChangeContext ctx, List<PatchSetApproval> del)
throws OrmException, IOException { throws OrmException, IOException {
LabelTypes labelTypes = ctx.getControl().getLabelTypes(); LabelTypes labelTypes = projectState.getLabelTypes(ctx.getNotes(), ctx.getUser());
Map<String, PatchSetApproval> current = new HashMap<>(); Map<String, PatchSetApproval> current = new HashMap<>();
for (PatchSetApproval a : for (PatchSetApproval a :

View File

@@ -42,6 +42,7 @@ import com.google.gerrit.server.mail.Address;
import com.google.gerrit.server.mail.send.AddReviewerSender; import com.google.gerrit.server.mail.send.AddReviewerSender;
import com.google.gerrit.server.notedb.NotesMigration; import com.google.gerrit.server.notedb.NotesMigration;
import com.google.gerrit.server.notedb.ReviewerStateInternal; import com.google.gerrit.server.notedb.ReviewerStateInternal;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.update.BatchUpdateOp; import com.google.gerrit.server.update.BatchUpdateOp;
import com.google.gerrit.server.update.ChangeContext; import com.google.gerrit.server.update.ChangeContext;
import com.google.gerrit.server.update.Context; import com.google.gerrit.server.update.Context;
@@ -94,6 +95,7 @@ public class PostReviewersOp implements BatchUpdateOp {
private final PatchSetUtil psUtil; private final PatchSetUtil psUtil;
private final ReviewerAdded reviewerAdded; private final ReviewerAdded reviewerAdded;
private final AccountCache accountCache; private final AccountCache accountCache;
private final ProjectCache projectCache;
private final AddReviewerSender.Factory addReviewerSenderFactory; private final AddReviewerSender.Factory addReviewerSenderFactory;
private final NotesMigration migration; private final NotesMigration migration;
private final Provider<IdentifiedUser> user; private final Provider<IdentifiedUser> user;
@@ -117,6 +119,7 @@ public class PostReviewersOp implements BatchUpdateOp {
PatchSetUtil psUtil, PatchSetUtil psUtil,
ReviewerAdded reviewerAdded, ReviewerAdded reviewerAdded,
AccountCache accountCache, AccountCache accountCache,
ProjectCache projectCache,
AddReviewerSender.Factory addReviewerSenderFactory, AddReviewerSender.Factory addReviewerSenderFactory,
NotesMigration migration, NotesMigration migration,
Provider<IdentifiedUser> user, Provider<IdentifiedUser> user,
@@ -131,6 +134,7 @@ public class PostReviewersOp implements BatchUpdateOp {
this.psUtil = psUtil; this.psUtil = psUtil;
this.reviewerAdded = reviewerAdded; this.reviewerAdded = reviewerAdded;
this.accountCache = accountCache; this.accountCache = accountCache;
this.projectCache = projectCache;
this.addReviewerSenderFactory = addReviewerSenderFactory; this.addReviewerSenderFactory = addReviewerSenderFactory;
this.migration = migration; this.migration = migration;
this.user = user; this.user = user;
@@ -161,7 +165,9 @@ public class PostReviewersOp implements BatchUpdateOp {
ctx.getDb(), ctx.getDb(),
ctx.getNotes(), ctx.getNotes(),
ctx.getUpdate(ctx.getChange().currentPatchSetId()), ctx.getUpdate(ctx.getChange().currentPatchSetId()),
rsrc.getControl().getLabelTypes(), projectCache
.checkedGet(rsrc.getProject())
.getLabelTypes(rsrc.getChange().getDest(), ctx.getUser()),
rsrc.getChange(), rsrc.getChange(),
reviewers); reviewers);
if (addedReviewers.isEmpty()) { if (addedReviewers.isEmpty()) {

View File

@@ -44,6 +44,8 @@ import com.google.gerrit.server.mail.send.CreateChangeSender;
import com.google.gerrit.server.mail.send.ReplacePatchSetSender; import com.google.gerrit.server.mail.send.ReplacePatchSetSender;
import com.google.gerrit.server.notedb.ChangeUpdate; import com.google.gerrit.server.notedb.ChangeUpdate;
import com.google.gerrit.server.patch.PatchSetInfoFactory; import com.google.gerrit.server.patch.PatchSetInfoFactory;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.update.BatchUpdate; import com.google.gerrit.server.update.BatchUpdate;
import com.google.gerrit.server.update.BatchUpdateOp; import com.google.gerrit.server.update.BatchUpdateOp;
import com.google.gerrit.server.update.ChangeContext; import com.google.gerrit.server.update.ChangeContext;
@@ -80,6 +82,7 @@ public class PublishDraftPatchSet
private final Provider<ReviewDb> dbProvider; private final Provider<ReviewDb> dbProvider;
private final ReplacePatchSetSender.Factory replacePatchSetFactory; private final ReplacePatchSetSender.Factory replacePatchSetFactory;
private final DraftPublished draftPublished; private final DraftPublished draftPublished;
private final ProjectCache projectCache;
@Inject @Inject
public PublishDraftPatchSet( public PublishDraftPatchSet(
@@ -91,7 +94,8 @@ public class PublishDraftPatchSet
PatchSetUtil psUtil, PatchSetUtil psUtil,
Provider<ReviewDb> dbProvider, Provider<ReviewDb> dbProvider,
ReplacePatchSetSender.Factory replacePatchSetFactory, ReplacePatchSetSender.Factory replacePatchSetFactory,
DraftPublished draftPublished) { DraftPublished draftPublished,
ProjectCache projectCache) {
super(retryHelper); super(retryHelper);
this.accountResolver = accountResolver; this.accountResolver = accountResolver;
this.approvalsUtil = approvalsUtil; this.approvalsUtil = approvalsUtil;
@@ -101,12 +105,13 @@ public class PublishDraftPatchSet
this.dbProvider = dbProvider; this.dbProvider = dbProvider;
this.replacePatchSetFactory = replacePatchSetFactory; this.replacePatchSetFactory = replacePatchSetFactory;
this.draftPublished = draftPublished; this.draftPublished = draftPublished;
this.projectCache = projectCache;
} }
@Override @Override
protected Response<?> applyImpl( protected Response<?> applyImpl(
BatchUpdate.Factory updateFactory, RevisionResource rsrc, Input input) BatchUpdate.Factory updateFactory, RevisionResource rsrc, Input input)
throws RestApiException, UpdateException { throws RestApiException, UpdateException, IOException {
return apply( return apply(
updateFactory, updateFactory,
rsrc.getUser(), rsrc.getUser(),
@@ -117,10 +122,10 @@ public class PublishDraftPatchSet
private Response<?> apply( private Response<?> apply(
BatchUpdate.Factory updateFactory, CurrentUser u, Change c, PatchSet.Id psId, PatchSet ps) BatchUpdate.Factory updateFactory, CurrentUser u, Change c, PatchSet.Id psId, PatchSet ps)
throws RestApiException, UpdateException { throws RestApiException, UpdateException, IOException {
try (BatchUpdate bu = try (BatchUpdate bu =
updateFactory.create(dbProvider.get(), c.getProject(), u, TimeUtil.nowTs())) { updateFactory.create(dbProvider.get(), c.getProject(), u, TimeUtil.nowTs())) {
bu.addOp(c.getId(), new Op(psId, ps)); bu.addOp(c.getId(), new Op(psId, projectCache.checkedGet(c.getProject()), ps));
bu.execute(); bu.execute();
} }
return Response.none(); return Response.none();
@@ -152,7 +157,7 @@ public class PublishDraftPatchSet
@Override @Override
protected Response<?> applyImpl( protected Response<?> applyImpl(
BatchUpdate.Factory updateFactory, ChangeResource rsrc, Input input) BatchUpdate.Factory updateFactory, ChangeResource rsrc, Input input)
throws RestApiException, UpdateException { throws RestApiException, UpdateException, IOException {
return publish.apply( return publish.apply(
updateFactory, updateFactory,
rsrc.getUser(), rsrc.getUser(),
@@ -164,6 +169,7 @@ public class PublishDraftPatchSet
private class Op implements BatchUpdateOp { private class Op implements BatchUpdateOp {
private final PatchSet.Id psId; private final PatchSet.Id psId;
private final ProjectState projectState;
private PatchSet patchSet; private PatchSet patchSet;
private Change change; private Change change;
@@ -171,8 +177,9 @@ public class PublishDraftPatchSet
private PatchSetInfo patchSetInfo; private PatchSetInfo patchSetInfo;
private MailRecipients recipients; private MailRecipients recipients;
private Op(PatchSet.Id psId, @Nullable PatchSet patchSet) { private Op(PatchSet.Id psId, ProjectState projectState, @Nullable PatchSet patchSet) {
this.psId = psId; this.psId = psId;
this.projectState = projectState;
this.patchSet = patchSet; this.patchSet = patchSet;
} }
@@ -212,7 +219,7 @@ public class PublishDraftPatchSet
} }
private void addReviewers(ChangeContext ctx) throws OrmException, IOException { private void addReviewers(ChangeContext ctx) throws OrmException, IOException {
LabelTypes labelTypes = ctx.getControl().getLabelTypes(); LabelTypes labelTypes = projectState.getLabelTypes(ctx.getNotes(), ctx.getUser());
Collection<Account.Id> oldReviewers = Collection<Account.Id> oldReviewers =
approvalsUtil.getReviewers(ctx.getDb(), ctx.getNotes()).all(); approvalsUtil.getReviewers(ctx.getDb(), ctx.getNotes()).all();
RevCommit commit = RevCommit commit =

View File

@@ -112,7 +112,8 @@ public class LabelNormalizer {
List<PatchSetApproval> unchanged = Lists.newArrayListWithCapacity(approvals.size()); List<PatchSetApproval> unchanged = Lists.newArrayListWithCapacity(approvals.size());
List<PatchSetApproval> updated = Lists.newArrayListWithCapacity(approvals.size()); List<PatchSetApproval> updated = Lists.newArrayListWithCapacity(approvals.size());
List<PatchSetApproval> deleted = Lists.newArrayListWithCapacity(approvals.size()); List<PatchSetApproval> deleted = Lists.newArrayListWithCapacity(approvals.size());
LabelTypes labelTypes = ctl.getLabelTypes(); LabelTypes labelTypes =
ctl.getProjectControl().getProjectState().getLabelTypes(ctl.getNotes(), ctl.getUser());
for (PatchSetApproval psa : approvals) { for (PatchSetApproval psa : approvals) {
Change.Id changeId = psa.getKey().getParentKey().getParentKey(); Change.Id changeId = psa.getKey().getParentKey().getParentKey();
checkArgument( checkArgument(

View File

@@ -455,7 +455,7 @@ class ReceiveCommits {
repo = rp.getRepository(); repo = rp.getRepository();
user = projectControl.getUser().asIdentifiedUser(); user = projectControl.getUser().asIdentifiedUser();
project = projectControl.getProject(); project = projectControl.getProject();
labelTypes = projectControl.getLabelTypes(); labelTypes = projectControl.getProjectState().getLabelTypes();
permissions = permissionBackend.user(user).project(project.getNameKey()); permissions = permissionBackend.user(user).project(project.getNameKey());
receiveId = RequestId.forProject(project.getNameKey()); receiveId = RequestId.forProject(project.getNameKey());
rejectCommits = BanCommit.loadRejectCommitsMap(rp.getRepository(), rp.getRevWalk()); rejectCommits = BanCommit.loadRejectCommitsMap(rp.getRepository(), rp.getRevWalk());

View File

@@ -52,7 +52,7 @@ import com.google.gerrit.server.mail.MailUtil.MailRecipients;
import com.google.gerrit.server.mail.send.ReplacePatchSetSender; import com.google.gerrit.server.mail.send.ReplacePatchSetSender;
import com.google.gerrit.server.notedb.ChangeNotes; import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.notedb.ChangeUpdate; import com.google.gerrit.server.notedb.ChangeUpdate;
import com.google.gerrit.server.project.ChangeControl; import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectControl; import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.server.query.change.ChangeData; import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.update.BatchUpdateOp; import com.google.gerrit.server.update.BatchUpdateOp;
@@ -103,7 +103,6 @@ public class ReplaceOp implements BatchUpdateOp {
private final AccountResolver accountResolver; private final AccountResolver accountResolver;
private final ApprovalCopier approvalCopier; private final ApprovalCopier approvalCopier;
private final ApprovalsUtil approvalsUtil; private final ApprovalsUtil approvalsUtil;
private final ChangeControl.GenericFactory changeControlFactory;
private final ChangeData.Factory changeDataFactory; private final ChangeData.Factory changeDataFactory;
private final ChangeKindCache changeKindCache; private final ChangeKindCache changeKindCache;
private final ChangeMessagesUtil cmUtil; private final ChangeMessagesUtil cmUtil;
@@ -115,6 +114,7 @@ public class ReplaceOp implements BatchUpdateOp {
private final MergedByPushOp.Factory mergedByPushOpFactory; private final MergedByPushOp.Factory mergedByPushOpFactory;
private final PatchSetUtil psUtil; private final PatchSetUtil psUtil;
private final ReplacePatchSetSender.Factory replacePatchSetFactory; private final ReplacePatchSetSender.Factory replacePatchSetFactory;
private final ProjectCache projectCache;
private final ProjectControl projectControl; private final ProjectControl projectControl;
private final Branch.NameKey dest; private final Branch.NameKey dest;
@@ -146,7 +146,6 @@ public class ReplaceOp implements BatchUpdateOp {
AccountResolver accountResolver, AccountResolver accountResolver,
ApprovalCopier approvalCopier, ApprovalCopier approvalCopier,
ApprovalsUtil approvalsUtil, ApprovalsUtil approvalsUtil,
ChangeControl.GenericFactory changeControlFactory,
ChangeData.Factory changeDataFactory, ChangeData.Factory changeDataFactory,
ChangeKindCache changeKindCache, ChangeKindCache changeKindCache,
ChangeMessagesUtil cmUtil, ChangeMessagesUtil cmUtil,
@@ -157,6 +156,7 @@ public class ReplaceOp implements BatchUpdateOp {
MergedByPushOp.Factory mergedByPushOpFactory, MergedByPushOp.Factory mergedByPushOpFactory,
PatchSetUtil psUtil, PatchSetUtil psUtil,
ReplacePatchSetSender.Factory replacePatchSetFactory, ReplacePatchSetSender.Factory replacePatchSetFactory,
ProjectCache projectCache,
@SendEmailExecutor ExecutorService sendEmailExecutor, @SendEmailExecutor ExecutorService sendEmailExecutor,
@Assisted ProjectControl projectControl, @Assisted ProjectControl projectControl,
@Assisted Branch.NameKey dest, @Assisted Branch.NameKey dest,
@@ -172,7 +172,6 @@ public class ReplaceOp implements BatchUpdateOp {
this.accountResolver = accountResolver; this.accountResolver = accountResolver;
this.approvalCopier = approvalCopier; this.approvalCopier = approvalCopier;
this.approvalsUtil = approvalsUtil; this.approvalsUtil = approvalsUtil;
this.changeControlFactory = changeControlFactory;
this.changeDataFactory = changeDataFactory; this.changeDataFactory = changeDataFactory;
this.changeKindCache = changeKindCache; this.changeKindCache = changeKindCache;
this.cmUtil = cmUtil; this.cmUtil = cmUtil;
@@ -183,6 +182,7 @@ public class ReplaceOp implements BatchUpdateOp {
this.mergedByPushOpFactory = mergedByPushOpFactory; this.mergedByPushOpFactory = mergedByPushOpFactory;
this.psUtil = psUtil; this.psUtil = psUtil;
this.replacePatchSetFactory = replacePatchSetFactory; this.replacePatchSetFactory = replacePatchSetFactory;
this.projectCache = projectCache;
this.sendEmailExecutor = sendEmailExecutor; this.sendEmailExecutor = sendEmailExecutor;
this.projectControl = projectControl; this.projectControl = projectControl;
@@ -304,7 +304,7 @@ public class ReplaceOp implements BatchUpdateOp {
approvalsUtil.addApprovalsForNewPatchSet( approvalsUtil.addApprovalsForNewPatchSet(
ctx.getDb(), ctx.getDb(),
update, update,
projectControl.getLabelTypes(), projectControl.getProjectState().getLabelTypes(),
newPatchSet, newPatchSet,
ctx.getControl(), ctx.getControl(),
approvals); approvals);
@@ -318,7 +318,7 @@ public class ReplaceOp implements BatchUpdateOp {
approvalsUtil.addReviewers( approvalsUtil.addReviewers(
ctx.getDb(), ctx.getDb(),
update, update,
projectControl.getLabelTypes(), projectControl.getProjectState().getLabelTypes(),
change, change,
newPatchSet, newPatchSet,
info, info,
@@ -409,7 +409,7 @@ public class ReplaceOp implements BatchUpdateOp {
continue; continue;
} }
LabelType lt = projectControl.getLabelTypes().byLabel(a.getLabelId()); LabelType lt = projectControl.getProjectState().getLabelTypes().byLabel(a.getLabelId());
if (lt != null) { if (lt != null) {
current.put(lt.getName(), a); current.put(lt.getName(), a);
} }
@@ -526,7 +526,7 @@ public class ReplaceOp implements BatchUpdateOp {
} }
} }
private void fireCommentAddedEvent(Context ctx) throws OrmException { private void fireCommentAddedEvent(Context ctx) throws IOException {
if (approvals.isEmpty()) { if (approvals.isEmpty()) {
return; return;
} }
@@ -536,9 +536,11 @@ public class ReplaceOp implements BatchUpdateOp {
* For labels that are set in this operation, the value was modified, so * For labels that are set in this operation, the value was modified, so
* show a transition from an oldValue of 0 to the new value. * show a transition from an oldValue of 0 to the new value.
*/ */
ChangeControl changeControl = List<LabelType> labels =
changeControlFactory.controlFor(ctx.getDb(), notes.getChange(), ctx.getUser()); projectCache
List<LabelType> labels = changeControl.getLabelTypes().getLabelTypes(); .checkedGet(ctx.getProject())
.getLabelTypes(notes, ctx.getUser())
.getLabelTypes();
Map<String, Short> allApprovals = new HashMap<>(); Map<String, Short> allApprovals = new HashMap<>();
Map<String, Short> oldApprovals = new HashMap<>(); Map<String, Short> oldApprovals = new HashMap<>();
for (LabelType lt : labels) { for (LabelType lt : labels) {

View File

@@ -18,14 +18,11 @@ import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Preconditions.checkState;
import static com.google.gerrit.server.permissions.LabelPermission.ForUser.ON_BEHALF_OF; import static com.google.gerrit.server.permissions.LabelPermission.ForUser.ON_BEHALF_OF;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.google.gerrit.common.Nullable; import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.data.LabelType; import com.google.gerrit.common.data.LabelType;
import com.google.gerrit.common.data.LabelTypes;
import com.google.gerrit.common.data.PermissionRange; import com.google.gerrit.common.data.PermissionRange;
import com.google.gerrit.common.data.RefConfigSection;
import com.google.gerrit.extensions.restapi.AuthException; import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.reviewdb.client.Account; import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change; import com.google.gerrit.reviewdb.client.Change;
@@ -272,29 +269,6 @@ public class ChangeControl {
return canAbandon(db) && refControl.asForRef().testOrFalse(RefPermission.CREATE_CHANGE); return canAbandon(db) && refControl.asForRef().testOrFalse(RefPermission.CREATE_CHANGE);
} }
/** All available label types for this change. */
public LabelTypes getLabelTypes() {
String destBranch = getChange().getDest().get();
List<LabelType> all = getProjectControl().getLabelTypes().getLabelTypes();
List<LabelType> r = Lists.newArrayListWithCapacity(all.size());
for (LabelType l : all) {
List<String> refs = l.getRefPatterns();
if (refs == null) {
r.add(l);
} else {
for (String refPattern : refs) {
if (RefConfigSection.isValid(refPattern) && match(destBranch, refPattern)) {
r.add(l);
break;
}
}
}
}
return new LabelTypes(r);
}
/** All value ranges of any allowed label permission. */ /** All value ranges of any allowed label permission. */
public List<PermissionRange> getLabelRanges() { public List<PermissionRange> getLabelRanges() {
return getRefControl().getLabelRanges(isOwner()); return getRefControl().getLabelRanges(isOwner());
@@ -326,7 +300,11 @@ public class ChangeControl {
for (PatchSetApproval ap : for (PatchSetApproval ap :
approvalsUtil.byPatchSet(db, this, getChange().currentPatchSetId(), null, null)) { approvalsUtil.byPatchSet(db, this, getChange().currentPatchSetId(), null, null)) {
LabelType type = getLabelTypes().byLabel(ap.getLabel()); LabelType type =
getProjectControl()
.getProjectState()
.getLabelTypes(getNotes(), getUser())
.byLabel(ap.getLabel());
if (type != null if (type != null
&& ap.getValue() == 1 && ap.getValue() == 1
&& type.getFunctionName().equalsIgnoreCase("PatchSetLock")) { && type.getFunctionName().equalsIgnoreCase("PatchSetLock")) {
@@ -403,10 +381,6 @@ public class ChangeControl {
|| getProjectControl().isAdmin(); || getProjectControl().isAdmin();
} }
private boolean match(String destBranch, String refPattern) {
return RefPatternMatcher.getMatcher(refPattern).match(destBranch, getUser());
}
private ChangeData changeData(ReviewDb db, @Nullable ChangeData cd) { private ChangeData changeData(ReviewDb db, @Nullable ChangeData cd) {
return cd != null ? cd : changeDataFactory.create(db, this); return cd != null ? cd : changeDataFactory.create(db, this);
} }

View File

@@ -24,7 +24,6 @@ import com.google.gerrit.common.data.AccessSection;
import com.google.gerrit.common.data.Capable; import com.google.gerrit.common.data.Capable;
import com.google.gerrit.common.data.ContributorAgreement; import com.google.gerrit.common.data.ContributorAgreement;
import com.google.gerrit.common.data.GroupReference; import com.google.gerrit.common.data.GroupReference;
import com.google.gerrit.common.data.LabelTypes;
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.common.data.PermissionRule.Action; import com.google.gerrit.common.data.PermissionRule.Action;
@@ -143,7 +142,6 @@ public class ProjectControl {
private List<SectionMatcher> allSections; private List<SectionMatcher> allSections;
private List<SectionMatcher> localSections; private List<SectionMatcher> localSections;
private LabelTypes labelTypes;
private Map<String, RefControl> refControls; private Map<String, RefControl> refControls;
private Boolean declaredOwner; private Boolean declaredOwner;
@@ -218,13 +216,6 @@ public class ProjectControl {
return state.getProject(); return state.getProject();
} }
public LabelTypes getLabelTypes() {
if (labelTypes == null) {
labelTypes = state.getLabelTypes();
}
return labelTypes;
}
/** Returns whether the project is hidden. */ /** Returns whether the project is hidden. */
private boolean isHidden() { private boolean isHidden() {
return getProject().getState().equals(com.google.gerrit.extensions.client.ProjectState.HIDDEN); return getProject().getState().equals(com.google.gerrit.extensions.client.ProjectState.HIDDEN);

View File

@@ -42,10 +42,10 @@ public class ProjectJson {
this.webLinks = webLinks; this.webLinks = webLinks;
} }
public ProjectInfo format(ProjectState state) { public ProjectInfo format(ProjectState projectState) {
ProjectInfo info = format(state.getProject()); ProjectInfo info = format(projectState.getProject());
info.labels = new HashMap<>(); info.labels = new HashMap<>();
for (LabelType t : state.getLabelTypes().getLabelTypes()) { for (LabelType t : projectState.getLabelTypes().getLabelTypes()) {
LabelTypeInfo labelInfo = new LabelTypeInfo(); LabelTypeInfo labelInfo = new LabelTypeInfo();
labelInfo.values = labelInfo.values =
t.getValues() t.getValues()

View File

@@ -27,6 +27,7 @@ import com.google.gerrit.common.data.LabelType;
import com.google.gerrit.common.data.LabelTypes; import com.google.gerrit.common.data.LabelTypes;
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.common.data.RefConfigSection;
import com.google.gerrit.common.data.SubscribeSection; import com.google.gerrit.common.data.SubscribeSection;
import com.google.gerrit.extensions.api.projects.CommentLinkInfo; import com.google.gerrit.extensions.api.projects.CommentLinkInfo;
import com.google.gerrit.extensions.api.projects.ThemeInfo; import com.google.gerrit.extensions.api.projects.ThemeInfo;
@@ -46,6 +47,7 @@ import com.google.gerrit.server.git.BranchOrderSection;
import com.google.gerrit.server.git.GitRepositoryManager; import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.ProjectConfig; import com.google.gerrit.server.git.ProjectConfig;
import com.google.gerrit.server.git.ProjectLevelConfig; import com.google.gerrit.server.git.ProjectLevelConfig;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted; import com.google.inject.assistedinject.Assisted;
import com.googlecode.prolog_cafe.exceptions.CompileException; import com.googlecode.prolog_cafe.exceptions.CompileException;
@@ -109,6 +111,9 @@ public class ProjectState {
/** If this is all projects, the capabilities used by the server. */ /** If this is all projects, the capabilities used by the server. */
private final CapabilityCollection capabilities; private final CapabilityCollection capabilities;
/** All label types applicable to changes in this project. */
private LabelTypes labelTypes;
@Inject @Inject
public ProjectState( public ProjectState(
final SitePaths sitePaths, final SitePaths sitePaths,
@@ -406,24 +411,39 @@ public class ProjectState {
return getInheritableBoolean(Project::getMatchAuthorToCommitterDate); return getInheritableBoolean(Project::getMatchAuthorToCommitterDate);
} }
/** All available label types. */
public LabelTypes getLabelTypes() { public LabelTypes getLabelTypes() {
Map<String, LabelType> types = new LinkedHashMap<>(); if (labelTypes == null) {
for (ProjectState s : treeInOrder()) { labelTypes = loadLabelTypes();
for (LabelType type : s.getConfig().getLabelSections().values()) { }
String lower = type.getName().toLowerCase(); return labelTypes;
LabelType old = types.get(lower); }
if (old == null || old.canOverride()) {
types.put(lower, type); /** All available label types for this change and user. */
public LabelTypes getLabelTypes(ChangeNotes notes, CurrentUser user) {
return getLabelTypes(notes.getChange().getDest(), user);
}
/** All available label types for this branch and user. */
public LabelTypes getLabelTypes(Branch.NameKey destination, CurrentUser user) {
List<LabelType> all = getLabelTypes().getLabelTypes();
List<LabelType> r = Lists.newArrayListWithCapacity(all.size());
for (LabelType l : all) {
List<String> refs = l.getRefPatterns();
if (refs == null) {
r.add(l);
} else {
for (String refPattern : refs) {
if (RefConfigSection.isValid(refPattern) && match(destination, refPattern, user)) {
r.add(l);
break;
}
} }
} }
} }
List<LabelType> all = Lists.newArrayListWithCapacity(types.size());
for (LabelType type : types.values()) { return new LabelTypes(r);
if (!type.getValues().isEmpty()) {
all.add(type);
}
}
return new LabelTypes(Collections.unmodifiableList(all));
} }
public List<CommentLinkInfo> getCommentLinks() { public List<CommentLinkInfo> getCommentLinks() {
@@ -522,4 +542,28 @@ public class ProjectState {
} }
return false; return false;
} }
private LabelTypes loadLabelTypes() {
Map<String, LabelType> types = new LinkedHashMap<>();
for (ProjectState s : treeInOrder()) {
for (LabelType type : s.getConfig().getLabelSections().values()) {
String lower = type.getName().toLowerCase();
LabelType old = types.get(lower);
if (old == null || old.canOverride()) {
types.put(lower, type);
}
}
}
List<LabelType> all = Lists.newArrayListWithCapacity(types.size());
for (LabelType type : types.values()) {
if (!type.getValues().isEmpty()) {
all.add(type);
}
}
return new LabelTypes(Collections.unmodifiableList(all));
}
private boolean match(Branch.NameKey destination, String refPattern, CurrentUser user) {
return RefPatternMatcher.getMatcher(refPattern).match(destination.get(), user);
}
} }

View File

@@ -73,6 +73,7 @@ import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gerrit.server.project.ChangeControl; import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.NoSuchChangeException; import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.project.ProjectCache; import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.project.SubmitRuleEvaluator; import com.google.gerrit.server.project.SubmitRuleEvaluator;
import com.google.gerrit.server.project.SubmitRuleOptions; import com.google.gerrit.server.project.SubmitRuleOptions;
import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.OrmException;
@@ -405,6 +406,7 @@ public class ChangeData {
private PersonIdent author; private PersonIdent author;
private PersonIdent committer; private PersonIdent committer;
private Integer unresolvedCommentCount; private Integer unresolvedCommentCount;
private LabelTypes labelTypes;
private ImmutableList<byte[]> refStates; private ImmutableList<byte[]> refStates;
private ImmutableList<byte[]> refStatePatterns; private ImmutableList<byte[]> refStatePatterns;
@@ -665,7 +667,17 @@ public class ChangeData {
} }
public LabelTypes getLabelTypes() throws OrmException { public LabelTypes getLabelTypes() throws OrmException {
return changeControl().getLabelTypes(); if (labelTypes == null) {
ProjectState state;
try {
state = projectCache.checkedGet(project());
} catch (IOException e) {
throw new OrmException("project state not available", e);
}
labelTypes =
state.getLabelTypes(changeControl().getChange().getDest(), changeControl().getUser());
}
return labelTypes;
} }
public ChangeNotes notes() throws OrmException { public ChangeNotes notes() throws OrmException {

View File

@@ -245,9 +245,7 @@ public class OutputStreamQuery {
private ChangeAttribute buildChangeAttribute( private ChangeAttribute buildChangeAttribute(
ChangeData d, Map<Project.NameKey, Repository> repos, Map<Project.NameKey, RevWalk> revWalks) ChangeData d, Map<Project.NameKey, Repository> repos, Map<Project.NameKey, RevWalk> revWalks)
throws OrmException, IOException { throws OrmException, IOException {
ChangeControl cc = d.changeControl().forUser(user); LabelTypes labelTypes = d.getLabelTypes();
LabelTypes labelTypes = cc.getLabelTypes();
ChangeAttribute c = eventFactory.asChangeAttribute(db, d.change()); ChangeAttribute c = eventFactory.asChangeAttribute(db, d.change());
eventFactory.extend(c, d.change()); eventFactory.extend(c, d.change());
@@ -299,6 +297,7 @@ public class OutputStreamQuery {
if (includeCurrentPatchSet) { if (includeCurrentPatchSet) {
PatchSet current = d.currentPatchSet(); PatchSet current = d.currentPatchSet();
ChangeControl cc = d.changeControl().forUser(user);
if (current != null && cc.isPatchVisible(current, d.db())) { if (current != null && cc.isPatchVisible(current, d.db())) {
c.currentPatchSet = eventFactory.asPatchSetAttribute(db, rw, d.change(), current); c.currentPatchSet = eventFactory.asPatchSetAttribute(db, rw, d.change(), current);
eventFactory.addApprovals(c.currentPatchSet, d.currentApprovals(), labelTypes); eventFactory.addApprovals(c.currentPatchSet, d.currentApprovals(), labelTypes);

View File

@@ -33,8 +33,9 @@ import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.OutputFormat; import com.google.gerrit.server.OutputFormat;
import com.google.gerrit.server.config.AllProjectsName; import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.project.NoSuchChangeException; import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.project.NoSuchProjectException; import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectControl; import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.util.LabelVote; import com.google.gerrit.server.util.LabelVote;
import com.google.gerrit.sshd.CommandMetaData; import com.google.gerrit.sshd.CommandMetaData;
import com.google.gerrit.sshd.SshCommand; import com.google.gerrit.sshd.SshCommand;
@@ -165,7 +166,7 @@ public class ReviewCommand extends SshCommand {
customLabels.put(v.label(), v.value()); customLabels.put(v.label(), v.value());
} }
@Inject private ProjectControl.Factory projectControlFactory; @Inject private ProjectCache projectCache;
@Inject private AllProjectsName allProjects; @Inject private AllProjectsName allProjects;
@@ -375,14 +376,14 @@ public class ReviewCommand extends SshCommand {
optionList = new ArrayList<>(); optionList = new ArrayList<>();
customLabels = new HashMap<>(); customLabels = new HashMap<>();
ProjectControl allProjectsControl; ProjectState allProjectsState;
try { try {
allProjectsControl = projectControlFactory.controlFor(allProjects); allProjectsState = projectCache.checkedGet(allProjects);
} catch (NoSuchProjectException e) { } catch (IOException e) {
throw die("missing " + allProjects.get()); throw die("missing " + allProjects.get());
} }
for (LabelType type : allProjectsControl.getLabelTypes().getLabelTypes()) { for (LabelType type : allProjectsState.getLabelTypes().getLabelTypes()) {
StringBuilder usage = new StringBuilder("score for ").append(type.getName()).append("\n"); StringBuilder usage = new StringBuilder("score for ").append(type.getName()).append("\n");
for (LabelValue v : type.getValues()) { for (LabelValue v : type.getValues()) {