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)));
detail.setConfigVisible(pc.isOwner() || checkReadConfig);
detail.setGroupInfo(buildGroupInfo(local));
detail.setLabelTypes(pc.getLabelTypes());
detail.setLabelTypes(pc.getProjectState().getLabelTypes());
detail.setFileHistoryLinks(getConfigFileLogLinks(projectName.get()));
return detail;
}

View File

@ -94,7 +94,6 @@ public class ChangeInserter implements InsertChangeOp {
private final PermissionBackend permissionBackend;
private final ProjectCache projectCache;
private final IdentifiedUser.GenericFactory userFactory;
private final ChangeControl.GenericFactory changeControlFactory;
private final PatchSetInfoFactory patchSetInfoFactory;
private final PatchSetUtil psUtil;
private final ApprovalsUtil approvalsUtil;
@ -144,7 +143,6 @@ public class ChangeInserter implements InsertChangeOp {
PermissionBackend permissionBackend,
ProjectCache projectCache,
IdentifiedUser.GenericFactory userFactory,
ChangeControl.GenericFactory changeControlFactory,
PatchSetInfoFactory patchSetInfoFactory,
PatchSetUtil psUtil,
ApprovalsUtil approvalsUtil,
@ -161,7 +159,6 @@ public class ChangeInserter implements InsertChangeOp {
this.permissionBackend = permissionBackend;
this.projectCache = projectCache;
this.userFactory = userFactory;
this.changeControlFactory = changeControlFactory;
this.patchSetInfoFactory = patchSetInfoFactory;
this.psUtil = psUtil;
this.approvalsUtil = approvalsUtil;
@ -436,7 +433,7 @@ public class ChangeInserter implements InsertChangeOp {
reviewersToAdd.addAll(extraCC);
}
LabelTypes labelTypes = ctl.getProjectControl().getLabelTypes();
LabelTypes labelTypes = ctl.getProjectControl().getProjectState().getLabelTypes();
approvalsUtil.addReviewers(
db,
update,
@ -493,7 +490,7 @@ public class ChangeInserter implements InsertChangeOp {
}
@Override
public void postUpdate(Context ctx) throws OrmException {
public void postUpdate(Context ctx) throws OrmException, IOException {
if (sendMail && (notify != NotifyHandling.NONE || !accountsToNotify.isEmpty())) {
Runnable sender =
new Runnable() {
@ -536,9 +533,11 @@ public class ChangeInserter implements InsertChangeOp {
if (fireRevisionCreated) {
revisionCreated.fire(change, patchSet, ctx.getAccount(), ctx.getWhen(), notify);
if (approvals != null && !approvals.isEmpty()) {
ChangeControl changeControl =
changeControlFactory.controlFor(ctx.getDb(), change, ctx.getUser());
List<LabelType> labels = changeControl.getLabelTypes().getLabelTypes();
List<LabelType> labels =
projectCache
.checkedGet(ctx.getProject())
.getLabelTypes(change.getDest(), ctx.getUser())
.getLabelTypes();
Map<String, Short> allApprovals = new HashMap<>();
Map<String, Short> oldApprovals = new HashMap<>();
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.NotesMigration;
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.update.BatchUpdateOp;
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.Provider;
import com.google.inject.assistedinject.Assisted;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@ -73,6 +75,7 @@ public class DeleteReviewerOp implements BatchUpdateOp {
private final NotesMigration migration;
private final NotifyUtil notifyUtil;
private final RemoveReviewerControl removeReviewerControl;
private final ProjectCache projectCache;
private final Account reviewer;
private final DeleteReviewerInput input;
@ -95,6 +98,7 @@ public class DeleteReviewerOp implements BatchUpdateOp {
NotesMigration migration,
NotifyUtil notifyUtil,
RemoveReviewerControl removeReviewerControl,
ProjectCache projectCache,
@Assisted Account reviewerAccount,
@Assisted DeleteReviewerInput input) {
this.approvalsUtil = approvalsUtil;
@ -107,14 +111,15 @@ public class DeleteReviewerOp implements BatchUpdateOp {
this.migration = migration;
this.notifyUtil = notifyUtil;
this.removeReviewerControl = removeReviewerControl;
this.projectCache = projectCache;
this.reviewer = reviewerAccount;
this.input = input;
}
@Override
public boolean updateChange(ChangeContext ctx)
throws AuthException, ResourceNotFoundException, OrmException, PermissionBackendException {
throws AuthException, ResourceNotFoundException, OrmException, PermissionBackendException,
IOException {
Account.Id reviewerId = reviewer.getId();
if (!approvalsUtil.getReviewers(ctx.getDb(), ctx.getNotes()).all().contains(reviewerId)) {
throw new ResourceNotFoundException();
@ -122,7 +127,8 @@ public class DeleteReviewerOp implements BatchUpdateOp {
currChange = ctx.getChange();
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
for (LabelType lt : labelTypes.getLabelTypes()) {
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.permissions.PermissionBackendException;
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.update.BatchUpdate;
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 NotifyUtil notifyUtil;
private final RemoveReviewerControl removeReviewerControl;
private final ProjectCache projectCache;
@Inject
DeleteVote(
@ -87,7 +90,8 @@ public class DeleteVote extends RetryingRestModifyView<VoteResource, DeleteVoteI
VoteDeleted voteDeleted,
DeleteVoteSender.Factory deleteVoteSenderFactory,
NotifyUtil notifyUtil,
RemoveReviewerControl removeReviewerControl) {
RemoveReviewerControl removeReviewerControl,
ProjectCache projectCache) {
super(retryHelper);
this.db = db;
this.approvalsUtil = approvalsUtil;
@ -98,12 +102,13 @@ public class DeleteVote extends RetryingRestModifyView<VoteResource, DeleteVoteI
this.deleteVoteSenderFactory = deleteVoteSenderFactory;
this.notifyUtil = notifyUtil;
this.removeReviewerControl = removeReviewerControl;
this.projectCache = projectCache;
}
@Override
protected Response<?> applyImpl(
BatchUpdate.Factory updateFactory, VoteResource rsrc, DeleteVoteInput input)
throws RestApiException, UpdateException {
throws RestApiException, UpdateException, IOException {
if (input == null) {
input = new DeleteVoteInput();
}
@ -123,7 +128,13 @@ public class DeleteVote extends RetryingRestModifyView<VoteResource, DeleteVoteI
try (BatchUpdate bu =
updateFactory.create(
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();
}
@ -131,16 +142,19 @@ public class DeleteVote extends RetryingRestModifyView<VoteResource, DeleteVoteI
}
private class Op implements BatchUpdateOp {
private final ProjectState projectState;
private final Account account;
private final String label;
private final DeleteVoteInput input;
private ChangeMessage changeMessage;
private Change change;
private PatchSet ps;
private Map<String, Short> newApprovals = 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.label = label;
this.input = input;
@ -156,7 +170,7 @@ public class DeleteVote extends RetryingRestModifyView<VoteResource, DeleteVoteI
ps = psUtil.current(db.get(), ctl.getNotes());
boolean found = false;
LabelTypes labelTypes = ctx.getControl().getLabelTypes();
LabelTypes labelTypes = projectState.getLabelTypes(ctx.getNotes(), ctx.getUser());
for (PatchSetApproval a :
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.PermissionBackendException;
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.update.BatchUpdate;
import com.google.gerrit.server.update.BatchUpdateOp;
@ -159,6 +161,7 @@ public class PostReview
private final NotifyUtil notifyUtil;
private final Config gerritConfig;
private final WorkInProgressOp.Factory workInProgressOpFactory;
private final ProjectCache projectCache;
@Inject
PostReview(
@ -178,7 +181,8 @@ public class PostReview
NotesMigration migration,
NotifyUtil notifyUtil,
@GerritServerConfig Config gerritConfig,
WorkInProgressOp.Factory workInProgressOpFactory) {
WorkInProgressOp.Factory workInProgressOpFactory,
ProjectCache projectCache) {
super(retryHelper);
this.db = db;
this.changes = changes;
@ -196,6 +200,7 @@ public class PostReview
this.notifyUtil = notifyUtil;
this.gerritConfig = gerritConfig;
this.workInProgressOpFactory = workInProgressOpFactory;
this.projectCache = projectCache;
}
@Override
@ -215,13 +220,15 @@ public class PostReview
if (revision.getEdit().isPresent()) {
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) {
revision = onBehalfOf(revision, input);
revision = onBehalfOf(revision, labelTypes, input);
} else if (input.drafts == null) {
input.drafts = DraftHandling.DELETE;
}
if (input.labels != null) {
checkLabels(revision, input.strictLabels, input.labels);
checkLabels(revision, labelTypes, input.strictLabels, input.labels);
}
if (input.comments != null) {
cleanUpComments(input.comments);
@ -348,7 +355,7 @@ public class PostReview
// Add the review op.
bu.addOp(
revision.getChange().getId(),
new Op(revision.getPatchSet().getId(), input, accountsToNotify));
new Op(projectState, revision.getPatchSet().getId(), input, accountsToNotify));
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,
PermissionBackendException, IOException, ConfigInvalidException {
if (in.labels == null || in.labels.isEmpty()) {
@ -427,7 +434,6 @@ public class PostReview
CurrentUser caller = rev.getUser();
PermissionBackend.ForChange perm = rev.permissions().database(db);
LabelTypes labelTypes = rev.getControl().getLabelTypes();
Iterator<Map.Entry<String, Short>> itr = in.labels.entrySet().iterator();
while (itr.hasNext()) {
Map.Entry<String, Short> ent = itr.next();
@ -468,14 +474,14 @@ public class PostReview
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 {
LabelTypes types = rsrc.getControl().getLabelTypes();
PermissionBackend.ForChange perm = rsrc.permissions();
Iterator<Map.Entry<String, Short>> itr = labels.entrySet().iterator();
while (itr.hasNext()) {
Map.Entry<String, Short> ent = itr.next();
LabelType lt = types.byLabel(ent.getKey());
LabelType lt = labelTypes.byLabel(ent.getKey());
if (lt == null) {
if (strict) {
throw new BadRequestException(
@ -810,6 +816,7 @@ public class PostReview
}
private class Op implements BatchUpdateOp {
private final ProjectState projectState;
private final PatchSet.Id psId;
private final ReviewInput in;
private final ListMultimap<RecipientType, Account.Id> accountsToNotify;
@ -824,9 +831,11 @@ public class PostReview
private Map<String, Short> oldApprovals = new HashMap<>();
private Op(
ProjectState projectState,
PatchSet.Id psId,
ReviewInput in,
ListMultimap<RecipientType, Account.Id> accountsToNotify) {
this.projectState = projectState;
this.psId = psId;
this.in = in;
this.accountsToNotify = checkNotNull(accountsToNotify);
@ -841,7 +850,7 @@ public class PostReview
boolean dirty = false;
dirty |= insertComments(ctx);
dirty |= insertRobotComments(ctx);
dirty |= updateLabels(ctx);
dirty |= updateLabels(projectState, ctx);
dirty |= insertMessage(ctx);
return dirty;
}
@ -1107,7 +1116,7 @@ public class PostReview
return false;
}
private boolean updateLabels(ChangeContext ctx)
private boolean updateLabels(ProjectState projectState, ChangeContext ctx)
throws OrmException, ResourceConflictException, IOException {
Map<String, Short> inLabels =
MoreObjects.firstNonNull(in.labels, Collections.<String, Short>emptyMap());
@ -1121,8 +1130,8 @@ public class PostReview
List<PatchSetApproval> del = new ArrayList<>();
List<PatchSetApproval> ups = new ArrayList<>();
Map<String, PatchSetApproval> current = scanLabels(ctx, del);
LabelTypes labelTypes = ctx.getControl().getLabelTypes();
Map<String, PatchSetApproval> current = scanLabels(projectState, ctx, del);
LabelTypes labelTypes = projectState.getLabelTypes(ctx.getNotes(), ctx.getUser());
Map<String, Short> allApprovals =
getAllApprovals(labelTypes, approvalsByKey(current.values()), inLabels);
Map<String, Short> previous =
@ -1182,7 +1191,7 @@ public class PostReview
return false;
}
forceCallerAsReviewer(ctx, current, ups, del);
forceCallerAsReviewer(projectState, ctx, current, ups, del);
ctx.getDb().patchSetApprovals().delete(del);
ctx.getDb().patchSetApprovals().upsert(ups);
return !del.isEmpty() || !ups.isEmpty();
@ -1260,6 +1269,7 @@ public class PostReview
}
private void forceCallerAsReviewer(
ProjectState projectState,
ChangeContext ctx,
Map<String, PatchSetApproval> current,
List<PatchSetApproval> ups,
@ -1269,7 +1279,12 @@ public class PostReview
if (del.isEmpty()) {
// If no existing label is being set to 0, hack in the caller
// 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());
c.setTag(in.tag);
c.setGranted(ctx.getWhen());
@ -1287,9 +1302,10 @@ public class PostReview
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 {
LabelTypes labelTypes = ctx.getControl().getLabelTypes();
LabelTypes labelTypes = projectState.getLabelTypes(ctx.getNotes(), ctx.getUser());
Map<String, PatchSetApproval> current = new HashMap<>();
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.notedb.NotesMigration;
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.ChangeContext;
import com.google.gerrit.server.update.Context;
@ -94,6 +95,7 @@ public class PostReviewersOp implements BatchUpdateOp {
private final PatchSetUtil psUtil;
private final ReviewerAdded reviewerAdded;
private final AccountCache accountCache;
private final ProjectCache projectCache;
private final AddReviewerSender.Factory addReviewerSenderFactory;
private final NotesMigration migration;
private final Provider<IdentifiedUser> user;
@ -117,6 +119,7 @@ public class PostReviewersOp implements BatchUpdateOp {
PatchSetUtil psUtil,
ReviewerAdded reviewerAdded,
AccountCache accountCache,
ProjectCache projectCache,
AddReviewerSender.Factory addReviewerSenderFactory,
NotesMigration migration,
Provider<IdentifiedUser> user,
@ -131,6 +134,7 @@ public class PostReviewersOp implements BatchUpdateOp {
this.psUtil = psUtil;
this.reviewerAdded = reviewerAdded;
this.accountCache = accountCache;
this.projectCache = projectCache;
this.addReviewerSenderFactory = addReviewerSenderFactory;
this.migration = migration;
this.user = user;
@ -161,7 +165,9 @@ public class PostReviewersOp implements BatchUpdateOp {
ctx.getDb(),
ctx.getNotes(),
ctx.getUpdate(ctx.getChange().currentPatchSetId()),
rsrc.getControl().getLabelTypes(),
projectCache
.checkedGet(rsrc.getProject())
.getLabelTypes(rsrc.getChange().getDest(), ctx.getUser()),
rsrc.getChange(),
reviewers);
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.notedb.ChangeUpdate;
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.BatchUpdateOp;
import com.google.gerrit.server.update.ChangeContext;
@ -80,6 +82,7 @@ public class PublishDraftPatchSet
private final Provider<ReviewDb> dbProvider;
private final ReplacePatchSetSender.Factory replacePatchSetFactory;
private final DraftPublished draftPublished;
private final ProjectCache projectCache;
@Inject
public PublishDraftPatchSet(
@ -91,7 +94,8 @@ public class PublishDraftPatchSet
PatchSetUtil psUtil,
Provider<ReviewDb> dbProvider,
ReplacePatchSetSender.Factory replacePatchSetFactory,
DraftPublished draftPublished) {
DraftPublished draftPublished,
ProjectCache projectCache) {
super(retryHelper);
this.accountResolver = accountResolver;
this.approvalsUtil = approvalsUtil;
@ -101,12 +105,13 @@ public class PublishDraftPatchSet
this.dbProvider = dbProvider;
this.replacePatchSetFactory = replacePatchSetFactory;
this.draftPublished = draftPublished;
this.projectCache = projectCache;
}
@Override
protected Response<?> applyImpl(
BatchUpdate.Factory updateFactory, RevisionResource rsrc, Input input)
throws RestApiException, UpdateException {
throws RestApiException, UpdateException, IOException {
return apply(
updateFactory,
rsrc.getUser(),
@ -117,10 +122,10 @@ public class PublishDraftPatchSet
private Response<?> apply(
BatchUpdate.Factory updateFactory, CurrentUser u, Change c, PatchSet.Id psId, PatchSet ps)
throws RestApiException, UpdateException {
throws RestApiException, UpdateException, IOException {
try (BatchUpdate bu =
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();
}
return Response.none();
@ -152,7 +157,7 @@ public class PublishDraftPatchSet
@Override
protected Response<?> applyImpl(
BatchUpdate.Factory updateFactory, ChangeResource rsrc, Input input)
throws RestApiException, UpdateException {
throws RestApiException, UpdateException, IOException {
return publish.apply(
updateFactory,
rsrc.getUser(),
@ -164,6 +169,7 @@ public class PublishDraftPatchSet
private class Op implements BatchUpdateOp {
private final PatchSet.Id psId;
private final ProjectState projectState;
private PatchSet patchSet;
private Change change;
@ -171,8 +177,9 @@ public class PublishDraftPatchSet
private PatchSetInfo patchSetInfo;
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.projectState = projectState;
this.patchSet = patchSet;
}
@ -212,7 +219,7 @@ public class PublishDraftPatchSet
}
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 =
approvalsUtil.getReviewers(ctx.getDb(), ctx.getNotes()).all();
RevCommit commit =

View File

@ -112,7 +112,8 @@ public class LabelNormalizer {
List<PatchSetApproval> unchanged = Lists.newArrayListWithCapacity(approvals.size());
List<PatchSetApproval> updated = 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) {
Change.Id changeId = psa.getKey().getParentKey().getParentKey();
checkArgument(

View File

@ -455,7 +455,7 @@ class ReceiveCommits {
repo = rp.getRepository();
user = projectControl.getUser().asIdentifiedUser();
project = projectControl.getProject();
labelTypes = projectControl.getLabelTypes();
labelTypes = projectControl.getProjectState().getLabelTypes();
permissions = permissionBackend.user(user).project(project.getNameKey());
receiveId = RequestId.forProject(project.getNameKey());
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.notedb.ChangeNotes;
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.query.change.ChangeData;
import com.google.gerrit.server.update.BatchUpdateOp;
@ -103,7 +103,6 @@ public class ReplaceOp implements BatchUpdateOp {
private final AccountResolver accountResolver;
private final ApprovalCopier approvalCopier;
private final ApprovalsUtil approvalsUtil;
private final ChangeControl.GenericFactory changeControlFactory;
private final ChangeData.Factory changeDataFactory;
private final ChangeKindCache changeKindCache;
private final ChangeMessagesUtil cmUtil;
@ -115,6 +114,7 @@ public class ReplaceOp implements BatchUpdateOp {
private final MergedByPushOp.Factory mergedByPushOpFactory;
private final PatchSetUtil psUtil;
private final ReplacePatchSetSender.Factory replacePatchSetFactory;
private final ProjectCache projectCache;
private final ProjectControl projectControl;
private final Branch.NameKey dest;
@ -146,7 +146,6 @@ public class ReplaceOp implements BatchUpdateOp {
AccountResolver accountResolver,
ApprovalCopier approvalCopier,
ApprovalsUtil approvalsUtil,
ChangeControl.GenericFactory changeControlFactory,
ChangeData.Factory changeDataFactory,
ChangeKindCache changeKindCache,
ChangeMessagesUtil cmUtil,
@ -157,6 +156,7 @@ public class ReplaceOp implements BatchUpdateOp {
MergedByPushOp.Factory mergedByPushOpFactory,
PatchSetUtil psUtil,
ReplacePatchSetSender.Factory replacePatchSetFactory,
ProjectCache projectCache,
@SendEmailExecutor ExecutorService sendEmailExecutor,
@Assisted ProjectControl projectControl,
@Assisted Branch.NameKey dest,
@ -172,7 +172,6 @@ public class ReplaceOp implements BatchUpdateOp {
this.accountResolver = accountResolver;
this.approvalCopier = approvalCopier;
this.approvalsUtil = approvalsUtil;
this.changeControlFactory = changeControlFactory;
this.changeDataFactory = changeDataFactory;
this.changeKindCache = changeKindCache;
this.cmUtil = cmUtil;
@ -183,6 +182,7 @@ public class ReplaceOp implements BatchUpdateOp {
this.mergedByPushOpFactory = mergedByPushOpFactory;
this.psUtil = psUtil;
this.replacePatchSetFactory = replacePatchSetFactory;
this.projectCache = projectCache;
this.sendEmailExecutor = sendEmailExecutor;
this.projectControl = projectControl;
@ -304,7 +304,7 @@ public class ReplaceOp implements BatchUpdateOp {
approvalsUtil.addApprovalsForNewPatchSet(
ctx.getDb(),
update,
projectControl.getLabelTypes(),
projectControl.getProjectState().getLabelTypes(),
newPatchSet,
ctx.getControl(),
approvals);
@ -318,7 +318,7 @@ public class ReplaceOp implements BatchUpdateOp {
approvalsUtil.addReviewers(
ctx.getDb(),
update,
projectControl.getLabelTypes(),
projectControl.getProjectState().getLabelTypes(),
change,
newPatchSet,
info,
@ -409,7 +409,7 @@ public class ReplaceOp implements BatchUpdateOp {
continue;
}
LabelType lt = projectControl.getLabelTypes().byLabel(a.getLabelId());
LabelType lt = projectControl.getProjectState().getLabelTypes().byLabel(a.getLabelId());
if (lt != null) {
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()) {
return;
}
@ -536,9 +536,11 @@ public class ReplaceOp implements BatchUpdateOp {
* 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.
*/
ChangeControl changeControl =
changeControlFactory.controlFor(ctx.getDb(), notes.getChange(), ctx.getUser());
List<LabelType> labels = changeControl.getLabelTypes().getLabelTypes();
List<LabelType> labels =
projectCache
.checkedGet(ctx.getProject())
.getLabelTypes(notes, ctx.getUser())
.getLabelTypes();
Map<String, Short> allApprovals = new HashMap<>();
Map<String, Short> oldApprovals = new HashMap<>();
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.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.Sets;
import com.google.gerrit.common.Nullable;
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.RefConfigSection;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
@ -272,29 +269,6 @@ public class ChangeControl {
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. */
public List<PermissionRange> getLabelRanges() {
return getRefControl().getLabelRanges(isOwner());
@ -326,7 +300,11 @@ public class ChangeControl {
for (PatchSetApproval ap :
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
&& ap.getValue() == 1
&& type.getFunctionName().equalsIgnoreCase("PatchSetLock")) {
@ -403,10 +381,6 @@ public class ChangeControl {
|| getProjectControl().isAdmin();
}
private boolean match(String destBranch, String refPattern) {
return RefPatternMatcher.getMatcher(refPattern).match(destBranch, getUser());
}
private ChangeData changeData(ReviewDb db, @Nullable ChangeData cd) {
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.ContributorAgreement;
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.PermissionRule;
import com.google.gerrit.common.data.PermissionRule.Action;
@ -143,7 +142,6 @@ public class ProjectControl {
private List<SectionMatcher> allSections;
private List<SectionMatcher> localSections;
private LabelTypes labelTypes;
private Map<String, RefControl> refControls;
private Boolean declaredOwner;
@ -218,13 +216,6 @@ public class ProjectControl {
return state.getProject();
}
public LabelTypes getLabelTypes() {
if (labelTypes == null) {
labelTypes = state.getLabelTypes();
}
return labelTypes;
}
/** Returns whether the project is hidden. */
private boolean isHidden() {
return getProject().getState().equals(com.google.gerrit.extensions.client.ProjectState.HIDDEN);

View File

@ -42,10 +42,10 @@ public class ProjectJson {
this.webLinks = webLinks;
}
public ProjectInfo format(ProjectState state) {
ProjectInfo info = format(state.getProject());
public ProjectInfo format(ProjectState projectState) {
ProjectInfo info = format(projectState.getProject());
info.labels = new HashMap<>();
for (LabelType t : state.getLabelTypes().getLabelTypes()) {
for (LabelType t : projectState.getLabelTypes().getLabelTypes()) {
LabelTypeInfo labelInfo = new LabelTypeInfo();
labelInfo.values =
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.Permission;
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.extensions.api.projects.CommentLinkInfo;
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.ProjectConfig;
import com.google.gerrit.server.git.ProjectLevelConfig;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
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. */
private final CapabilityCollection capabilities;
/** All label types applicable to changes in this project. */
private LabelTypes labelTypes;
@Inject
public ProjectState(
final SitePaths sitePaths,
@ -406,24 +411,39 @@ public class ProjectState {
return getInheritableBoolean(Project::getMatchAuthorToCommitterDate);
}
/** All available label types. */
public LabelTypes getLabelTypes() {
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);
if (labelTypes == null) {
labelTypes = loadLabelTypes();
}
return labelTypes;
}
/** 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()) {
if (!type.getValues().isEmpty()) {
all.add(type);
}
}
return new LabelTypes(Collections.unmodifiableList(all));
return new LabelTypes(r);
}
public List<CommentLinkInfo> getCommentLinks() {
@ -522,4 +542,28 @@ public class ProjectState {
}
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.NoSuchChangeException;
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.SubmitRuleOptions;
import com.google.gwtorm.server.OrmException;
@ -405,6 +406,7 @@ public class ChangeData {
private PersonIdent author;
private PersonIdent committer;
private Integer unresolvedCommentCount;
private LabelTypes labelTypes;
private ImmutableList<byte[]> refStates;
private ImmutableList<byte[]> refStatePatterns;
@ -665,7 +667,17 @@ public class ChangeData {
}
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 {

View File

@ -245,9 +245,7 @@ public class OutputStreamQuery {
private ChangeAttribute buildChangeAttribute(
ChangeData d, Map<Project.NameKey, Repository> repos, Map<Project.NameKey, RevWalk> revWalks)
throws OrmException, IOException {
ChangeControl cc = d.changeControl().forUser(user);
LabelTypes labelTypes = cc.getLabelTypes();
LabelTypes labelTypes = d.getLabelTypes();
ChangeAttribute c = eventFactory.asChangeAttribute(db, d.change());
eventFactory.extend(c, d.change());
@ -299,6 +297,7 @@ public class OutputStreamQuery {
if (includeCurrentPatchSet) {
PatchSet current = d.currentPatchSet();
ChangeControl cc = d.changeControl().forUser(user);
if (current != null && cc.isPatchVisible(current, d.db())) {
c.currentPatchSet = eventFactory.asPatchSetAttribute(db, rw, d.change(), current);
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.config.AllProjectsName;
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.ProjectState;
import com.google.gerrit.server.util.LabelVote;
import com.google.gerrit.sshd.CommandMetaData;
import com.google.gerrit.sshd.SshCommand;
@ -165,7 +166,7 @@ public class ReviewCommand extends SshCommand {
customLabels.put(v.label(), v.value());
}
@Inject private ProjectControl.Factory projectControlFactory;
@Inject private ProjectCache projectCache;
@Inject private AllProjectsName allProjects;
@ -375,14 +376,14 @@ public class ReviewCommand extends SshCommand {
optionList = new ArrayList<>();
customLabels = new HashMap<>();
ProjectControl allProjectsControl;
ProjectState allProjectsState;
try {
allProjectsControl = projectControlFactory.controlFor(allProjects);
} catch (NoSuchProjectException e) {
allProjectsState = projectCache.checkedGet(allProjects);
} catch (IOException e) {
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");
for (LabelValue v : type.getValues()) {