Merge "ChangeJson: Remove ChangeControl"

This commit is contained in:
Edwin Kempin
2017-09-19 11:53:16 +00:00
committed by Gerrit Code Review
4 changed files with 53 additions and 63 deletions

View File

@@ -408,7 +408,7 @@ public class ActionsIT extends AbstractDaemonTest {
revisionInfo = revisionInfo =
changeJsonFactory changeJsonFactory
.create(opts) .create(opts)
.getRevisionInfo(cd.changeControl(), cd.patchSet(new PatchSet.Id(changeId, 1))); .getRevisionInfo(cd, cd.patchSet(new PatchSet.Id(changeId, 1)));
} }
private void visitedCurrentRevisionActionsAssertions( private void visitedCurrentRevisionActionsAssertions(

View File

@@ -119,7 +119,6 @@ import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gerrit.server.permissions.LabelPermission; 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.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.RemoveReviewerControl; import com.google.gerrit.server.project.RemoveReviewerControl;
@@ -166,7 +165,7 @@ public class ChangeJson {
ChangeField.SUBMIT_RULE_OPTIONS_STRICT.toBuilder().fastEvalLabels(true).build(); ChangeField.SUBMIT_RULE_OPTIONS_STRICT.toBuilder().fastEvalLabels(true).build();
public static final ImmutableSet<ListChangesOption> REQUIRE_LAZY_LOAD = public static final ImmutableSet<ListChangesOption> REQUIRE_LAZY_LOAD =
ImmutableSet.of(ALL_REVISIONS, MESSAGES); ImmutableSet.of(ALL_REVISIONS, CHANGE_ACTIONS, CHECK, CURRENT_ACTIONS, MESSAGES);
@Singleton @Singleton
public static class Factory { public static class Factory {
@@ -430,9 +429,9 @@ public class ChangeJson {
} }
private ChangeInfo checkOnly(ChangeData cd) { private ChangeInfo checkOnly(ChangeData cd) {
ChangeControl ctl; ChangeNotes notes;
try { try {
ctl = cd.changeControl().forUser(userProvider.get()); notes = cd.notes();
} catch (OrmException e) { } catch (OrmException e) {
String msg = "Error loading change"; String msg = "Error loading change";
log.warn(msg + " " + cd.getId(), e); log.warn(msg + " " + cd.getId(), e);
@@ -444,7 +443,7 @@ public class ChangeJson {
return info; return info;
} }
ConsistencyChecker.Result result = checkerProvider.get().check(ctl.getNotes(), fix); ConsistencyChecker.Result result = checkerProvider.get().check(notes, fix);
ChangeInfo info; ChangeInfo info;
Change c = result.change(); Change c = result.change();
if (c != null) { if (c != null) {
@@ -477,10 +476,9 @@ public class ChangeJson {
PermissionBackendException { PermissionBackendException {
ChangeInfo out = new ChangeInfo(); ChangeInfo out = new ChangeInfo();
CurrentUser user = userProvider.get(); CurrentUser user = userProvider.get();
ChangeControl ctl = cd.changeControl().forUser(user);
if (has(CHECK)) { if (has(CHECK)) {
out.problems = checkerProvider.get().check(ctl.getNotes(), fix).problems(); out.problems = checkerProvider.get().check(cd.notes(), fix).problems();
// If any problems were fixed, the ChangeData needs to be reloaded. // If any problems were fixed, the ChangeData needs to be reloaded.
for (ProblemInfo p : out.problems) { for (ProblemInfo p : out.problems) {
if (p.status == ProblemInfo.Status.FIXED) { if (p.status == ProblemInfo.Status.FIXED) {
@@ -549,7 +547,7 @@ public class ChangeJson {
} }
} }
out.labels = labelsFor(perm, ctl, cd, has(LABELS), has(DETAILED_LABELS)); out.labels = labelsFor(perm, cd, has(LABELS), has(DETAILED_LABELS));
if (out.labels != null && has(DETAILED_LABELS)) { if (out.labels != null && has(DETAILED_LABELS)) {
// If limited to specific patch sets but not the current patch set, don't // If limited to specific patch sets but not the current patch set, don't
@@ -564,7 +562,7 @@ public class ChangeJson {
out.reviewers = reviewerMap(cd.reviewers(), cd.reviewersByEmail(), false); out.reviewers = reviewerMap(cd.reviewers(), cd.reviewersByEmail(), false);
out.pendingReviewers = reviewerMap(cd.pendingReviewers(), cd.pendingReviewersByEmail(), true); out.pendingReviewers = reviewerMap(cd.pendingReviewers(), cd.pendingReviewersByEmail(), true);
out.removableReviewers = removableReviewers(ctl, out); out.removableReviewers = removableReviewers(cd, out);
} }
setSubmitter(cd, out); setSubmitter(cd, out);
@@ -585,14 +583,14 @@ public class ChangeJson {
src = null; src = null;
} }
if (needMessages) { if (needMessages) {
out.messages = messages(ctl, cd, src); out.messages = messages(cd, src);
} }
finish(out); finish(out);
// This block must come after the ChangeInfo is mostly populated, since // This block must come after the ChangeInfo is mostly populated, since
// it will be passed to ActionVisitors as-is. // it will be passed to ActionVisitors as-is.
if (needRevisions) { if (needRevisions) {
out.revisions = revisions(ctl, cd, src, limitToPsId, out); out.revisions = revisions(cd, src, limitToPsId, out);
if (out.revisions != null) { if (out.revisions != null) {
for (Map.Entry<String, RevisionInfo> entry : out.revisions.entrySet()) { for (Map.Entry<String, RevisionInfo> entry : out.revisions.entrySet()) {
if (entry.getValue().isCurrent) { if (entry.getValue().isCurrent) {
@@ -604,7 +602,7 @@ public class ChangeJson {
} }
if (has(CURRENT_ACTIONS) || has(CHANGE_ACTIONS)) { if (has(CURRENT_ACTIONS) || has(CHANGE_ACTIONS)) {
actionJson.addChangeActions(out, ctl.getNotes()); actionJson.addChangeActions(out, cd.notes());
} }
if (has(TRACKING_IDS)) { if (has(TRACKING_IDS)) {
@@ -658,20 +656,12 @@ public class ChangeJson {
} }
private Map<String, LabelInfo> labelsFor( private Map<String, LabelInfo> labelsFor(
PermissionBackend.ForChange perm, PermissionBackend.ForChange perm, ChangeData cd, boolean standard, boolean detailed)
ChangeControl ctl,
ChangeData cd,
boolean standard,
boolean detailed)
throws OrmException, PermissionBackendException { throws OrmException, PermissionBackendException {
if (!standard && !detailed) { if (!standard && !detailed) {
return null; return null;
} }
if (ctl == null) {
return null;
}
LabelTypes labelTypes = cd.getLabelTypes(); LabelTypes labelTypes = cd.getLabelTypes();
Map<String, LabelWithStatus> withStatus = Map<String, LabelWithStatus> withStatus =
cd.change().getStatus() == Change.Status.MERGED cd.change().getStatus() == Change.Status.MERGED
@@ -1095,8 +1085,8 @@ public class ChangeJson {
return result; return result;
} }
private Collection<ChangeMessageInfo> messages( private Collection<ChangeMessageInfo> messages(ChangeData cd, Map<PatchSet.Id, PatchSet> map)
ChangeControl ctl, ChangeData cd, Map<PatchSet.Id, PatchSet> map) throws OrmException { throws OrmException {
List<ChangeMessage> messages = cmUtil.byChange(db.get(), cd.notes()); List<ChangeMessage> messages = cmUtil.byChange(db.get(), cd.notes());
if (messages.isEmpty()) { if (messages.isEmpty()) {
return Collections.emptyList(); return Collections.emptyList();
@@ -1106,7 +1096,7 @@ public class ChangeJson {
for (ChangeMessage message : messages) { for (ChangeMessage message : messages) {
PatchSet.Id patchNum = message.getPatchSetId(); PatchSet.Id patchNum = message.getPatchSetId();
PatchSet ps = patchNum != null ? map.get(patchNum) : null; PatchSet ps = patchNum != null ? map.get(patchNum) : null;
if (patchNum == null || ctl.isPatchVisible(ps, db.get())) { if (patchNum == null || cd.changeControl().isPatchVisible(ps, db.get())) {
ChangeMessageInfo cmi = new ChangeMessageInfo(); ChangeMessageInfo cmi = new ChangeMessageInfo();
cmi.id = message.getKey().get(); cmi.id = message.getKey().get();
cmi.author = accountLoader.get(message.getAuthor()); cmi.author = accountLoader.get(message.getAuthor());
@@ -1124,8 +1114,8 @@ public class ChangeJson {
return result; return result;
} }
private Collection<AccountInfo> removableReviewers(ChangeControl ctl, ChangeInfo out) private Collection<AccountInfo> removableReviewers(ChangeData cd, ChangeInfo out)
throws PermissionBackendException, NoSuchChangeException { throws PermissionBackendException, NoSuchChangeException, OrmException {
// Although this is called removableReviewers, this method also determines // Although this is called removableReviewers, this method also determines
// which CCs are removable. // which CCs are removable.
// //
@@ -1147,7 +1137,7 @@ public class ChangeJson {
Account.Id id = new Account.Id(ai._accountId); Account.Id id = new Account.Id(ai._accountId);
if (removeReviewerControl.testRemoveReviewer( if (removeReviewerControl.testRemoveReviewer(
ctl.getNotes(), ctl.getUser(), id, MoreObjects.firstNonNull(ai.value, 0))) { cd, userProvider.get(), id, MoreObjects.firstNonNull(ai.value, 0))) {
removable.add(id); removable.add(id);
} else { } else {
fixed.add(id); fixed.add(id);
@@ -1164,7 +1154,7 @@ public class ChangeJson {
for (AccountInfo ai : ccs) { for (AccountInfo ai : ccs) {
if (ai._accountId != null) { if (ai._accountId != null) {
Account.Id id = new Account.Id(ai._accountId); Account.Id id = new Account.Id(ai._accountId);
if (removeReviewerControl.testRemoveReviewer(ctl.getNotes(), ctl.getUser(), id, 0)) { if (removeReviewerControl.testRemoveReviewer(cd, userProvider.get(), id, 0)) {
removable.add(id); removable.add(id);
} }
} }
@@ -1208,9 +1198,9 @@ public class ChangeJson {
} }
@Nullable @Nullable
private Repository openRepoIfNecessary(ChangeControl ctl) throws IOException { private Repository openRepoIfNecessary(Project.NameKey project) throws IOException {
if (has(ALL_COMMITS) || has(CURRENT_COMMIT) || has(COMMIT_FOOTERS)) { if (has(ALL_COMMITS) || has(CURRENT_COMMIT) || has(COMMIT_FOOTERS)) {
return repoManager.openRepository(ctl.getProject().getNameKey()); return repoManager.openRepository(project);
} }
return null; return null;
} }
@@ -1221,14 +1211,13 @@ public class ChangeJson {
} }
private Map<String, RevisionInfo> revisions( private Map<String, RevisionInfo> revisions(
ChangeControl ctl,
ChangeData cd, ChangeData cd,
Map<PatchSet.Id, PatchSet> map, Map<PatchSet.Id, PatchSet> map,
Optional<PatchSet.Id> limitToPsId, Optional<PatchSet.Id> limitToPsId,
ChangeInfo changeInfo) ChangeInfo changeInfo)
throws PatchListNotAvailableException, GpgException, OrmException, IOException { throws PatchListNotAvailableException, GpgException, OrmException, IOException {
Map<String, RevisionInfo> res = new LinkedHashMap<>(); Map<String, RevisionInfo> res = new LinkedHashMap<>();
try (Repository repo = openRepoIfNecessary(ctl); try (Repository repo = openRepoIfNecessary(cd.project());
RevWalk rw = newRevWalk(repo)) { RevWalk rw = newRevWalk(repo)) {
for (PatchSet in : map.values()) { for (PatchSet in : map.values()) {
PatchSet.Id id = in.getId(); PatchSet.Id id = in.getId();
@@ -1238,10 +1227,10 @@ public class ChangeJson {
} else if (limitToPsId.isPresent()) { } else if (limitToPsId.isPresent()) {
want = id.equals(limitToPsId.get()); want = id.equals(limitToPsId.get());
} else { } else {
want = id.equals(ctl.getChange().currentPatchSetId()); want = id.equals(cd.change().currentPatchSetId());
} }
if (want && ctl.isPatchVisible(in, db.get())) { if (want && cd.changeControl().isPatchVisible(in, db.get())) {
res.put(in.getRevision().get(), toRevisionInfo(ctl, cd, in, repo, rw, false, changeInfo)); res.put(in.getRevision().get(), toRevisionInfo(cd, in, repo, rw, false, changeInfo));
} }
} }
return res; return res;
@@ -1275,20 +1264,18 @@ public class ChangeJson {
return map; return map;
} }
public RevisionInfo getRevisionInfo(ChangeControl ctl, PatchSet in) public RevisionInfo getRevisionInfo(ChangeData cd, PatchSet in)
throws PatchListNotAvailableException, GpgException, OrmException, IOException { throws PatchListNotAvailableException, GpgException, OrmException, IOException {
accountLoader = accountLoaderFactory.create(has(DETAILED_ACCOUNTS)); accountLoader = accountLoaderFactory.create(has(DETAILED_ACCOUNTS));
try (Repository repo = openRepoIfNecessary(ctl); try (Repository repo = openRepoIfNecessary(cd.project());
RevWalk rw = newRevWalk(repo)) { RevWalk rw = newRevWalk(repo)) {
RevisionInfo rev = RevisionInfo rev = toRevisionInfo(cd, in, repo, rw, true, null);
toRevisionInfo(ctl, changeDataFactory.create(db.get(), ctl), in, repo, rw, true, null);
accountLoader.fill(); accountLoader.fill();
return rev; return rev;
} }
} }
private RevisionInfo toRevisionInfo( private RevisionInfo toRevisionInfo(
ChangeControl ctl,
ChangeData cd, ChangeData cd,
PatchSet in, PatchSet in,
@Nullable Repository repo, @Nullable Repository repo,
@@ -1296,7 +1283,7 @@ public class ChangeJson {
boolean fillCommit, boolean fillCommit,
@Nullable ChangeInfo changeInfo) @Nullable ChangeInfo changeInfo)
throws PatchListNotAvailableException, GpgException, OrmException, IOException { throws PatchListNotAvailableException, GpgException, OrmException, IOException {
Change c = ctl.getChange(); Change c = cd.change();
RevisionInfo out = new RevisionInfo(); RevisionInfo out = new RevisionInfo();
out.isCurrent = in.getId().equals(c.currentPatchSetId()); out.isCurrent = in.getId().equals(c.currentPatchSetId());
out._number = in.getId().get(); out._number = in.getId().get();
@@ -1304,7 +1291,7 @@ public class ChangeJson {
out.created = in.getCreatedOn(); out.created = in.getCreatedOn();
out.uploader = accountLoader.get(in.getUploader()); out.uploader = accountLoader.get(in.getUploader());
out.draft = in.isDraft() ? true : null; out.draft = in.isDraft() ? true : null;
out.fetch = makeFetchMap(ctl, in); out.fetch = makeFetchMap(cd, in);
out.kind = changeKindCache.getChangeKind(rw, repo != null ? repo.getConfig() : null, cd, in); out.kind = changeKindCache.getChangeKind(rw, repo != null ? repo.getConfig() : null, cd, in);
out.description = in.getDescription(); out.description = in.getDescription();
@@ -1321,7 +1308,7 @@ public class ChangeJson {
out.commit = toCommit(project, rw, commit, has(WEB_LINKS), fillCommit); out.commit = toCommit(project, rw, commit, has(WEB_LINKS), fillCommit);
} }
if (addFooters) { if (addFooters) {
Ref ref = repo.exactRef(ctl.getChange().getDest().get()); Ref ref = repo.exactRef(cd.change().getDest().get());
RevCommit mergeTip = null; RevCommit mergeTip = null;
if (ref != null) { if (ref != null) {
mergeTip = rw.parseCommit(ref.getObjectId()); mergeTip = rw.parseCommit(ref.getObjectId());
@@ -1331,7 +1318,7 @@ public class ChangeJson {
mergeUtilFactory mergeUtilFactory
.create(projectCache.get(project)) .create(projectCache.get(project))
.createCommitMessageOnSubmit( .createCommitMessageOnSubmit(
commit, mergeTip, ctl.getNotes(), ctl.getUser(), in.getId()); commit, mergeTip, cd.notes(), userProvider.get(), in.getId());
} }
} }
@@ -1348,7 +1335,7 @@ public class ChangeJson {
actionJson.addRevisionActions( actionJson.addRevisionActions(
changeInfo, changeInfo,
out, out,
new RevisionResource(changeResourceFactory.create(ctl.getNotes(), ctl.getUser()), in)); new RevisionResource(changeResourceFactory.create(cd.notes(), userProvider.get()), in));
} }
if (gpgApi.isEnabled() && has(PUSH_CERTIFICATES)) { if (gpgApi.isEnabled() && has(PUSH_CERTIFICATES)) {
@@ -1396,7 +1383,7 @@ public class ChangeJson {
return info; return info;
} }
private Map<String, FetchInfo> makeFetchMap(ChangeControl ctl, PatchSet in) throws OrmException { private Map<String, FetchInfo> makeFetchMap(ChangeData cd, PatchSet in) throws OrmException {
Map<String, FetchInfo> r = new LinkedHashMap<>(); Map<String, FetchInfo> r = new LinkedHashMap<>();
for (DynamicMap.Entry<DownloadScheme> e : downloadSchemes) { for (DynamicMap.Entry<DownloadScheme> e : downloadSchemes) {
@@ -1407,11 +1394,12 @@ public class ChangeJson {
continue; continue;
} }
if (!scheme.isAuthSupported() && !ctl.forUser(anonymous).isPatchVisible(in, db.get())) { if (!scheme.isAuthSupported()
&& !cd.changeControl().forUser(anonymous).isPatchVisible(in, db.get())) {
continue; continue;
} }
String projectName = ctl.getProject().getNameKey().get(); String projectName = cd.project().get();
String url = scheme.getUrl(projectName); String url = scheme.getUrl(projectName);
String refName = in.getRefName(); String refName = in.getRefName();
FetchInfo fetchInfo = new FetchInfo(url, refName); FetchInfo fetchInfo = new FetchInfo(url, refName);

View File

@@ -29,7 +29,6 @@ import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.GpgException; import com.google.gerrit.server.GpgException;
import com.google.gerrit.server.change.ChangeJson; import com.google.gerrit.server.change.ChangeJson;
import com.google.gerrit.server.patch.PatchListNotAvailableException; import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.query.change.ChangeData; import com.google.gerrit.server.query.change.ChangeData;
import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject; import com.google.inject.Inject;
@@ -88,8 +87,7 @@ public class EventUtil {
public RevisionInfo revisionInfo(Project.NameKey project, PatchSet ps) public RevisionInfo revisionInfo(Project.NameKey project, PatchSet ps)
throws OrmException, PatchListNotAvailableException, GpgException, IOException { throws OrmException, PatchListNotAvailableException, GpgException, IOException {
ChangeData cd = changeDataFactory.create(db.get(), project, ps.getId().getParentKey()); ChangeData cd = changeDataFactory.create(db.get(), project, ps.getId().getParentKey());
ChangeControl ctl = cd.changeControl(); return changeJson.getRevisionInfo(cd, ps);
return changeJson.getRevisionInfo(ctl, ps);
} }
public AccountInfo accountInfo(Account a) { public AccountInfo accountInfo(Account a) {

View File

@@ -16,6 +16,7 @@ package com.google.gerrit.server.project;
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.PatchSetApproval; import com.google.gerrit.reviewdb.client.PatchSetApproval;
import com.google.gerrit.reviewdb.server.ReviewDb; import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.CurrentUser; import com.google.gerrit.server.CurrentUser;
@@ -23,6 +24,8 @@ import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.permissions.ChangePermission; import com.google.gerrit.server.permissions.ChangePermission;
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.query.change.ChangeData;
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.Singleton; import com.google.inject.Singleton;
@@ -46,9 +49,9 @@ public class RemoveReviewerControl {
/** @throws AuthException if this user is not allowed to remove this approval. */ /** @throws AuthException if this user is not allowed to remove this approval. */
public void checkRemoveReviewer( public void checkRemoveReviewer(
ChangeNotes notes, CurrentUser currentUser, PatchSetApproval approval) ChangeNotes notes, CurrentUser currentUser, PatchSetApproval approval)
throws PermissionBackendException, AuthException, NoSuchChangeException { throws PermissionBackendException, AuthException, NoSuchChangeException, OrmException {
if (canRemoveReviewerWithoutPermissionCheck( if (canRemoveReviewerWithoutPermissionCheck(
notes, currentUser, approval.getAccountId(), approval.getValue())) { notes.getChange(), currentUser, approval.getAccountId(), approval.getValue())) {
return; return;
} }
@@ -61,22 +64,22 @@ public class RemoveReviewerControl {
/** @return true if the user is allowed to remove this reviewer. */ /** @return true if the user is allowed to remove this reviewer. */
public boolean testRemoveReviewer( public boolean testRemoveReviewer(
ChangeNotes notes, CurrentUser currentUser, Account.Id reviewer, int value) ChangeData cd, CurrentUser currentUser, Account.Id reviewer, int value)
throws PermissionBackendException, NoSuchChangeException { throws PermissionBackendException, NoSuchChangeException, OrmException {
if (canRemoveReviewerWithoutPermissionCheck(notes, currentUser, reviewer, value)) { if (canRemoveReviewerWithoutPermissionCheck(cd.change(), currentUser, reviewer, value)) {
return true; return true;
} }
return permissionBackend return permissionBackend
.user(currentUser) .user(currentUser)
.change(notes) .change(cd)
.database(dbProvider) .database(dbProvider)
.test(ChangePermission.REMOVE_REVIEWER); .test(ChangePermission.REMOVE_REVIEWER);
} }
private boolean canRemoveReviewerWithoutPermissionCheck( private boolean canRemoveReviewerWithoutPermissionCheck(
ChangeNotes notes, CurrentUser currentUser, Account.Id reviewer, int value) Change change, CurrentUser currentUser, Account.Id reviewer, int value)
throws NoSuchChangeException { throws NoSuchChangeException, OrmException {
if (!notes.getChange().getStatus().isOpen()) { if (!change.getStatus().isOpen()) {
return false; return false;
} }
@@ -84,14 +87,15 @@ public class RemoveReviewerControl {
Account.Id aId = currentUser.getAccountId(); Account.Id aId = currentUser.getAccountId();
if (aId.equals(reviewer)) { if (aId.equals(reviewer)) {
return true; // A user can always remove themselves. return true; // A user can always remove themselves.
} else if (aId.equals(notes.getChange().getOwner()) && 0 <= value) { } else if (aId.equals(change.getOwner()) && 0 <= value) {
return true; // The change owner may remove any zero or positive score. return true; // The change owner may remove any zero or positive score.
} }
} }
// Users with the remove reviewer permission, the branch owner, project // Users with the remove reviewer permission, the branch owner, project
// owner and site admin can remove anyone // owner and site admin can remove anyone
ChangeControl changeControl = changeControlFactory.controlFor(notes, currentUser); ChangeControl changeControl =
changeControlFactory.controlFor(dbProvider.get(), change, currentUser);
if (changeControl.getRefControl().isOwner() // branch owner if (changeControl.getRefControl().isOwner() // branch owner
|| changeControl.getProjectControl().isOwner() // project owner || changeControl.getProjectControl().isOwner() // project owner
|| changeControl.getProjectControl().isAdmin()) { // project admin || changeControl.getProjectControl().isAdmin()) { // project admin