Reduce usage of ChangeControl

Reduce the usage of ChangeControl by replacing it with ChangeNotes and
CurrentUser where it was just used as a container for these.

Change return type of ChangeResource#getUser from IdentifiedUser to
CurrentUser to be more versatile and allow individual endpoints to check
if the user is an identified user. Since anonymous users can also
access some change resources it seems more consistent to only assume
that we can get a CurrentUser from ChangeResource.

Eventually, {Ref,Change,Project}Control should be package-private. This
commit is an incremental step towards that goal.

Change-Id: I6790f6f9d56240a96aa007bae140422b71c59750
This commit is contained in:
Patrick Hiesel
2017-08-25 16:49:25 +02:00
parent ef213fd3e0
commit 42eda45540
34 changed files with 184 additions and 232 deletions

View File

@@ -133,7 +133,7 @@ public class CatServlet extends HttpServlet {
.check(ChangePermission.READ); .check(ChangePermission.READ);
if (patchKey.getParentKey().get() == 0) { if (patchKey.getParentKey().get() == 0) {
// change edit // change edit
Optional<ChangeEdit> edit = changeEditUtil.byChange(notes.getChange()); Optional<ChangeEdit> edit = changeEditUtil.byChange(notes);
if (edit.isPresent()) { if (edit.isPresent()) {
revision = ObjectId.toString(edit.get().getEditCommit()); revision = ObjectId.toString(edit.get().getEditCommit());
} else { } else {

View File

@@ -172,7 +172,7 @@ public class ChangeEditApiImpl implements ChangeEditApi {
@Override @Override
public void modifyFile(String filePath, RawInput newContent) throws RestApiException { public void modifyFile(String filePath, RawInput newContent) throws RestApiException {
try { try {
changeEditsPut.apply(changeResource.getControl(), filePath, newContent); changeEditsPut.apply(changeResource, filePath, newContent);
} catch (Exception e) { } catch (Exception e) {
throw asRestApiException("Cannot modify file of change edit", e); throw asRestApiException("Cannot modify file of change edit", e);
} }
@@ -181,7 +181,7 @@ public class ChangeEditApiImpl implements ChangeEditApi {
@Override @Override
public void deleteFile(String filePath) throws RestApiException { public void deleteFile(String filePath) throws RestApiException {
try { try {
changeEditDeleteContent.apply(changeResource.getControl(), filePath); changeEditDeleteContent.apply(changeResource, filePath);
} catch (Exception e) { } catch (Exception e) {
throw asRestApiException("Cannot delete file of change edit", e); throw asRestApiException("Cannot delete file of change edit", e);
} }

View File

@@ -32,6 +32,7 @@ import com.google.gerrit.reviewdb.client.Project;
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;
import com.google.gerrit.server.git.AbandonOp; import com.google.gerrit.server.git.AbandonOp;
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.PermissionBackendException; import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.project.ChangeControl; import com.google.gerrit.server.project.ChangeControl;
@@ -76,49 +77,58 @@ public class Abandon extends RetryingRestModifyView<ChangeResource, AbandonInput
IOException, ConfigInvalidException { IOException, ConfigInvalidException {
req.permissions().database(dbProvider).check(ChangePermission.ABANDON); req.permissions().database(dbProvider).check(ChangePermission.ABANDON);
NotifyHandling notify = input.notify == null ? defaultNotify(req.getControl()) : input.notify; NotifyHandling notify = input.notify == null ? defaultNotify(req.getChange()) : input.notify;
Change change = Change change =
abandon( abandon(
updateFactory, updateFactory,
req.getControl(), req.getNotes(),
req.getUser(),
input.message, input.message,
notify, notify,
notifyUtil.resolveAccounts(input.notifyDetails)); notifyUtil.resolveAccounts(input.notifyDetails));
return json.noOptions().format(change); return json.noOptions().format(change);
} }
private NotifyHandling defaultNotify(ChangeControl control) { private NotifyHandling defaultNotify(Change change) {
return control.getChange().hasReviewStarted() ? NotifyHandling.ALL : NotifyHandling.OWNER; return change.hasReviewStarted() ? NotifyHandling.ALL : NotifyHandling.OWNER;
} }
public Change abandon(BatchUpdate.Factory updateFactory, ChangeControl control) public Change abandon(BatchUpdate.Factory updateFactory, ChangeNotes notes, CurrentUser user)
throws RestApiException, UpdateException {
return abandon(updateFactory, control, "", defaultNotify(control), ImmutableListMultimap.of());
}
public Change abandon(BatchUpdate.Factory updateFactory, ChangeControl control, String msgTxt)
throws RestApiException, UpdateException { throws RestApiException, UpdateException {
return abandon( return abandon(
updateFactory, control, msgTxt, defaultNotify(control), ImmutableListMultimap.of()); updateFactory,
notes,
user,
"",
defaultNotify(notes.getChange()),
ImmutableListMultimap.of());
}
public Change abandon(
BatchUpdate.Factory updateFactory, ChangeNotes notes, CurrentUser user, String msgTxt)
throws RestApiException, UpdateException {
return abandon(
updateFactory,
notes,
user,
msgTxt,
defaultNotify(notes.getChange()),
ImmutableListMultimap.of());
} }
public Change abandon( public Change abandon(
BatchUpdate.Factory updateFactory, BatchUpdate.Factory updateFactory,
ChangeControl control, ChangeNotes notes,
CurrentUser user,
String msgTxt, String msgTxt,
NotifyHandling notifyHandling, NotifyHandling notifyHandling,
ListMultimap<RecipientType, Account.Id> accountsToNotify) ListMultimap<RecipientType, Account.Id> accountsToNotify)
throws RestApiException, UpdateException { throws RestApiException, UpdateException {
CurrentUser user = control.getUser();
Account account = user.isIdentifiedUser() ? user.asIdentifiedUser().getAccount() : null; Account account = user.isIdentifiedUser() ? user.asIdentifiedUser().getAccount() : null;
AbandonOp op = abandonOpFactory.create(account, msgTxt, notifyHandling, accountsToNotify); AbandonOp op = abandonOpFactory.create(account, msgTxt, notifyHandling, accountsToNotify);
try (BatchUpdate u = try (BatchUpdate u =
updateFactory.create( updateFactory.create(dbProvider.get(), notes.getProjectName(), user, TimeUtil.nowTs())) {
dbProvider.get(), u.addOp(notes.getChangeId(), op).execute();
control.getProject().getNameKey(),
control.getUser(),
TimeUtil.nowTs())) {
u.addOp(control.getId(), op).execute();
} }
return op.getChange(); return op.getChange();
} }

View File

@@ -75,7 +75,7 @@ public class ApplyFix implements RestModifyView<FixResource, Void> {
repository, projectState, patchSetCommitId, fixResource.getFixReplacements()); repository, projectState, patchSetCommitId, fixResource.getFixReplacements());
ChangeEdit changeEdit = ChangeEdit changeEdit =
changeEditModifier.combineWithModifiedPatchSetTree( changeEditModifier.combineWithModifiedPatchSetTree(
repository, revisionResource.getControl(), patchSet, treeModifications); repository, revisionResource.getNotes(), patchSet, treeModifications);
return Response.ok(changeEditJson.toEditInfo(changeEdit, false)); return Response.ok(changeEditJson.toEditInfo(changeEdit, false));
} catch (InvalidChangeOperationException e) { } catch (InvalidChangeOperationException e) {
throw new ResourceConflictException(e.getMessage()); throw new ResourceConflictException(e.getMessage());

View File

@@ -17,7 +17,6 @@ package com.google.gerrit.server.change;
import com.google.gerrit.extensions.restapi.RestResource; import com.google.gerrit.extensions.restapi.RestResource;
import com.google.gerrit.extensions.restapi.RestView; import com.google.gerrit.extensions.restapi.RestView;
import com.google.gerrit.server.edit.ChangeEdit; import com.google.gerrit.server.edit.ChangeEdit;
import com.google.gerrit.server.project.ChangeControl;
import com.google.inject.TypeLiteral; import com.google.inject.TypeLiteral;
/** /**
@@ -54,10 +53,6 @@ public class ChangeEditResource implements RestResource {
return change; return change;
} }
public ChangeControl getControl() {
return getChangeResource().getControl();
}
public ChangeEdit getChangeEdit() { public ChangeEdit getChangeEdit() {
return edit; return edit;
} }

View File

@@ -47,7 +47,6 @@ import com.google.gerrit.server.edit.UnchangedCommitMessageException;
import com.google.gerrit.server.git.GitRepositoryManager; import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.patch.PatchListNotAvailableException; import com.google.gerrit.server.patch.PatchListNotAvailableException;
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.InvalidChangeOperationException; import com.google.gerrit.server.project.InvalidChangeOperationException;
import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject; import com.google.inject.Inject;
@@ -105,7 +104,7 @@ public class ChangeEdits
@Override @Override
public ChangeEditResource parse(ChangeResource rsrc, IdString id) public ChangeEditResource parse(ChangeResource rsrc, IdString id)
throws ResourceNotFoundException, AuthException, IOException, OrmException { throws ResourceNotFoundException, AuthException, IOException, OrmException {
Optional<ChangeEdit> edit = editUtil.byChange(rsrc.getChange()); Optional<ChangeEdit> edit = editUtil.byChange(rsrc.getNotes(), rsrc.getUser());
if (!edit.isPresent()) { if (!edit.isPresent()) {
throw new ResourceNotFoundException(id); throw new ResourceNotFoundException(id);
} }
@@ -157,7 +156,7 @@ public class ChangeEdits
public Response<?> apply(ChangeResource resource, Put.Input input) public Response<?> apply(ChangeResource resource, Put.Input input)
throws AuthException, ResourceConflictException, IOException, OrmException, throws AuthException, ResourceConflictException, IOException, OrmException,
PermissionBackendException { PermissionBackendException {
putEdit.apply(resource.getControl(), path, input.content); putEdit.apply(resource, path, input.content);
return Response.none(); return Response.none();
} }
} }
@@ -182,7 +181,7 @@ public class ChangeEdits
public Response<?> apply(ChangeResource rsrc, DeleteFile.Input in) public Response<?> apply(ChangeResource rsrc, DeleteFile.Input in)
throws IOException, AuthException, ResourceConflictException, OrmException, throws IOException, AuthException, ResourceConflictException, OrmException,
PermissionBackendException { PermissionBackendException {
return deleteContent.apply(rsrc.getControl(), path); return deleteContent.apply(rsrc, path);
} }
} }
@@ -218,7 +217,7 @@ public class ChangeEdits
@Override @Override
public Response<EditInfo> apply(ChangeResource rsrc) public Response<EditInfo> apply(ChangeResource rsrc)
throws AuthException, IOException, ResourceNotFoundException, OrmException { throws AuthException, IOException, ResourceNotFoundException, OrmException {
Optional<ChangeEdit> edit = editUtil.byChange(rsrc.getChange()); Optional<ChangeEdit> edit = editUtil.byChange(rsrc.getNotes(), rsrc.getUser());
if (!edit.isPresent()) { if (!edit.isPresent()) {
return Response.none(); return Response.none();
} }
@@ -275,13 +274,12 @@ public class ChangeEdits
PermissionBackendException { PermissionBackendException {
Project.NameKey project = resource.getProject(); Project.NameKey project = resource.getProject();
try (Repository repository = repositoryManager.openRepository(project)) { try (Repository repository = repositoryManager.openRepository(project)) {
ChangeControl changeControl = resource.getControl();
if (isRestoreFile(input)) { if (isRestoreFile(input)) {
editModifier.restoreFile(repository, changeControl, input.restorePath); editModifier.restoreFile(repository, resource.getNotes(), input.restorePath);
} else if (isRenameFile(input)) { } else if (isRenameFile(input)) {
editModifier.renameFile(repository, changeControl, input.oldPath, input.newPath); editModifier.renameFile(repository, resource.getNotes(), input.oldPath, input.newPath);
} else { } else {
editModifier.createEdit(repository, changeControl); editModifier.createEdit(repository, resource.getNotes());
} }
} catch (InvalidChangeOperationException e) { } catch (InvalidChangeOperationException e) {
throw new ResourceConflictException(e.getMessage()); throw new ResourceConflictException(e.getMessage());
@@ -320,19 +318,18 @@ public class ChangeEdits
public Response<?> apply(ChangeEditResource rsrc, Input input) public Response<?> apply(ChangeEditResource rsrc, Input input)
throws AuthException, ResourceConflictException, IOException, OrmException, throws AuthException, ResourceConflictException, IOException, OrmException,
PermissionBackendException { PermissionBackendException {
return apply(rsrc.getControl(), rsrc.getPath(), input.content); return apply(rsrc.getChangeResource(), rsrc.getPath(), input.content);
} }
public Response<?> apply(ChangeControl changeControl, String path, RawInput newContent) public Response<?> apply(ChangeResource rsrc, String path, RawInput newContent)
throws ResourceConflictException, AuthException, IOException, OrmException, throws ResourceConflictException, AuthException, IOException, OrmException,
PermissionBackendException { PermissionBackendException {
if (Strings.isNullOrEmpty(path) || path.charAt(0) == '/') { if (Strings.isNullOrEmpty(path) || path.charAt(0) == '/') {
throw new ResourceConflictException("Invalid path: " + path); throw new ResourceConflictException("Invalid path: " + path);
} }
Project.NameKey project = changeControl.getChange().getProject(); try (Repository repository = repositoryManager.openRepository(rsrc.getProject())) {
try (Repository repository = repositoryManager.openRepository(project)) { editModifier.modifyFile(repository, rsrc.getNotes(), path, newContent);
editModifier.modifyFile(repository, changeControl, path, newContent);
} catch (InvalidChangeOperationException e) { } catch (InvalidChangeOperationException e) {
throw new ResourceConflictException(e.getMessage()); throw new ResourceConflictException(e.getMessage());
} }
@@ -364,15 +361,14 @@ public class ChangeEdits
public Response<?> apply(ChangeEditResource rsrc, DeleteContent.Input input) public Response<?> apply(ChangeEditResource rsrc, DeleteContent.Input input)
throws AuthException, ResourceConflictException, OrmException, IOException, throws AuthException, ResourceConflictException, OrmException, IOException,
PermissionBackendException { PermissionBackendException {
return apply(rsrc.getControl(), rsrc.getPath()); return apply(rsrc.getChangeResource(), rsrc.getPath());
} }
public Response<?> apply(ChangeControl changeControl, String filePath) public Response<?> apply(ChangeResource rsrc, String filePath)
throws AuthException, IOException, OrmException, ResourceConflictException, throws AuthException, IOException, OrmException, ResourceConflictException,
PermissionBackendException { PermissionBackendException {
Project.NameKey project = changeControl.getChange().getProject(); try (Repository repository = repositoryManager.openRepository(rsrc.getProject())) {
try (Repository repository = repositoryManager.openRepository(project)) { editModifier.deleteFile(repository, rsrc.getNotes(), filePath);
editModifier.deleteFile(repository, changeControl, filePath);
} catch (InvalidChangeOperationException e) { } catch (InvalidChangeOperationException e) {
throw new ResourceConflictException(e.getMessage()); throw new ResourceConflictException(e.getMessage());
} }
@@ -401,7 +397,7 @@ public class ChangeEdits
ChangeEdit edit = rsrc.getChangeEdit(); ChangeEdit edit = rsrc.getChangeEdit();
return Response.ok( return Response.ok(
fileContentUtil.getContent( fileContentUtil.getContent(
rsrc.getControl().getProjectControl().getProjectState(), rsrc.getChangeResource().getControl().getProjectControl().getProjectState(),
base base
? ObjectId.fromString(edit.getBasePatchSet().getRevision().get()) ? ObjectId.fromString(edit.getBasePatchSet().getRevision().get())
: edit.getEditCommit(), : edit.getEditCommit(),
@@ -471,8 +467,7 @@ public class ChangeEdits
Project.NameKey project = rsrc.getProject(); Project.NameKey project = rsrc.getProject();
try (Repository repository = repositoryManager.openRepository(project)) { try (Repository repository = repositoryManager.openRepository(project)) {
ChangeControl changeControl = rsrc.getControl(); editModifier.modifyMessage(repository, rsrc.getNotes(), input.message);
editModifier.modifyMessage(repository, changeControl, input.message);
} catch (UnchangedCommitMessageException e) { } catch (UnchangedCommitMessageException e) {
throw new ResourceConflictException(e.getMessage()); throw new ResourceConflictException(e.getMessage());
} }
@@ -501,7 +496,7 @@ public class ChangeEdits
@Override @Override
public BinaryResult apply(ChangeResource rsrc) public BinaryResult apply(ChangeResource rsrc)
throws AuthException, IOException, ResourceNotFoundException, OrmException { throws AuthException, IOException, ResourceNotFoundException, OrmException {
Optional<ChangeEdit> edit = editUtil.byChange(rsrc.getChange()); Optional<ChangeEdit> edit = editUtil.byChange(rsrc.getNotes(), rsrc.getUser());
String msg; String msg;
if (edit.isPresent()) { if (edit.isPresent()) {
if (base) { if (base) {

View File

@@ -18,10 +18,8 @@ import com.google.gerrit.extensions.api.changes.IncludedInInfo;
import com.google.gerrit.extensions.restapi.RestApiException; import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.RestReadView; import com.google.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.reviewdb.client.PatchSet; import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.server.ReviewDb; import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.PatchSetUtil; import com.google.gerrit.server.PatchSetUtil;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Provider; import com.google.inject.Provider;
@@ -44,9 +42,7 @@ public class ChangeIncludedIn implements RestReadView<ChangeResource> {
@Override @Override
public IncludedInInfo apply(ChangeResource rsrc) public IncludedInInfo apply(ChangeResource rsrc)
throws RestApiException, OrmException, IOException { throws RestApiException, OrmException, IOException {
ChangeControl ctl = rsrc.getControl();
PatchSet ps = psUtil.current(db.get(), rsrc.getNotes()); PatchSet ps = psUtil.current(db.get(), rsrc.getNotes());
Project.NameKey project = ctl.getProject().getNameKey(); return includedIn.apply(rsrc.getProject(), ps.getRevision().get());
return includedIn.apply(project, ps.getRevision().get());
} }
} }

View File

@@ -285,7 +285,7 @@ public class ChangeJson {
} }
public ChangeInfo format(ChangeResource rsrc) throws OrmException { public ChangeInfo format(ChangeResource rsrc) throws OrmException {
return format(changeDataFactory.create(db.get(), rsrc.getControl())); return format(changeDataFactory.create(db.get(), rsrc.getNotes()));
} }
public ChangeInfo format(Change change) throws OrmException { public ChangeInfo format(Change change) throws OrmException {

View File

@@ -27,7 +27,6 @@ import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Change; import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project; import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.CurrentUser; import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.StarredChangesUtil; import com.google.gerrit.server.StarredChangesUtil;
import com.google.gerrit.server.notedb.ChangeNotes; import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.permissions.PermissionBackend; import com.google.gerrit.server.permissions.PermissionBackend;
@@ -77,8 +76,8 @@ public class ChangeResource implements RestResource, HasETag {
return control; return control;
} }
public IdentifiedUser getUser() { public CurrentUser getUser() {
return getControl().getUser().asIdentifiedUser(); return getControl().getUser();
} }
public Change.Id getId() { public Change.Id getId() {

View File

@@ -42,7 +42,6 @@ import com.google.gerrit.server.git.MergeIdenticalTreeException;
import com.google.gerrit.server.git.MergeUtil; import com.google.gerrit.server.git.MergeUtil;
import com.google.gerrit.server.permissions.ChangePermission; import com.google.gerrit.server.permissions.ChangePermission;
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.CommitsCollection; import com.google.gerrit.server.project.CommitsCollection;
import com.google.gerrit.server.project.InvalidChangeOperationException; import com.google.gerrit.server.project.InvalidChangeOperationException;
import com.google.gerrit.server.project.ProjectControl; import com.google.gerrit.server.project.ProjectControl;
@@ -117,11 +116,10 @@ public class CreateMergePatchSet
throw new BadRequestException("merge.source must be non-empty"); throw new BadRequestException("merge.source must be non-empty");
} }
ChangeControl ctl = rsrc.getControl(); PatchSet ps = psUtil.current(db.get(), rsrc.getNotes());
PatchSet ps = psUtil.current(db.get(), ctl.getNotes()); ProjectControl projectControl = rsrc.getControl().getProjectControl();
ProjectControl projectControl = ctl.getProjectControl();
ProjectState state = projectControl.getProjectState(); ProjectState state = projectControl.getProjectState();
Change change = ctl.getChange(); Change change = rsrc.getChange();
Project.NameKey project = change.getProject(); Project.NameKey project = change.getProject();
Branch.NameKey dest = change.getDest(); Branch.NameKey dest = change.getDest();
try (Repository git = gitManager.openRepository(project); try (Repository git = gitManager.openRepository(project);
@@ -153,11 +151,12 @@ public class CreateMergePatchSet
ObjectId.fromString(change.getKey().get().substring(1))); ObjectId.fromString(change.getKey().get().substring(1)));
PatchSet.Id nextPsId = ChangeUtil.nextPatchSetId(ps.getId()); PatchSet.Id nextPsId = ChangeUtil.nextPatchSetId(ps.getId());
PatchSetInserter psInserter = patchSetInserterFactory.create(ctl, nextPsId, newCommit); PatchSetInserter psInserter =
patchSetInserterFactory.create(rsrc.getControl(), nextPsId, newCommit);
try (BatchUpdate bu = updateFactory.create(db.get(), project, me, now)) { try (BatchUpdate bu = updateFactory.create(db.get(), project, me, now)) {
bu.setRepository(git, rw, oi); bu.setRepository(git, rw, oi);
bu.addOp( bu.addOp(
ctl.getId(), rsrc.getId(),
psInserter psInserter
.setMessage("Uploaded patch set " + nextPsId.get() + ".") .setMessage("Uploaded patch set " + nextPsId.get() + ".")
.setDraft(ps.isDraft()) .setDraft(ps.isDraft())

View File

@@ -41,7 +41,7 @@ public class DeleteChangeEdit implements RestModifyView<ChangeResource, Input> {
@Override @Override
public Response<?> apply(ChangeResource rsrc, Input input) public Response<?> apply(ChangeResource rsrc, Input input)
throws AuthException, ResourceNotFoundException, IOException, OrmException { throws AuthException, ResourceNotFoundException, IOException, OrmException {
Optional<ChangeEdit> edit = editUtil.byChange(rsrc.getChange()); Optional<ChangeEdit> edit = editUtil.byChange(rsrc.getNotes(), rsrc.getUser());
if (edit.isPresent()) { if (edit.isPresent()) {
editUtil.delete(edit.get()); editUtil.delete(edit.get());
} else { } else {

View File

@@ -27,7 +27,6 @@ import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ChangeMessagesUtil; import com.google.gerrit.server.ChangeMessagesUtil;
import com.google.gerrit.server.permissions.GlobalPermission; import com.google.gerrit.server.permissions.GlobalPermission;
import com.google.gerrit.server.permissions.PermissionBackend; import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.update.BatchUpdate; import com.google.gerrit.server.update.BatchUpdate;
import com.google.gerrit.server.update.RetryHelper; import com.google.gerrit.server.update.RetryHelper;
import com.google.gerrit.server.update.RetryingRestModifyView; import com.google.gerrit.server.update.RetryingRestModifyView;
@@ -67,15 +66,11 @@ public class DeletePrivate
throw new ResourceConflictException("change is not private"); throw new ResourceConflictException("change is not private");
} }
ChangeControl control = rsrc.getControl();
SetPrivateOp op = new SetPrivateOp(cmUtil, false, input); SetPrivateOp op = new SetPrivateOp(cmUtil, false, input);
try (BatchUpdate u = try (BatchUpdate u =
updateFactory.create( updateFactory.create(
dbProvider.get(), dbProvider.get(), rsrc.getProject(), rsrc.getUser(), TimeUtil.nowTs())) {
control.getProject().getNameKey(), u.addOp(rsrc.getId(), op).execute();
control.getUser(),
TimeUtil.nowTs())) {
u.addOp(control.getId(), op).execute();
} }
return Response.none(); return Response.none();

View File

@@ -19,7 +19,6 @@ import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.Response; import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.RestReadView; import com.google.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.server.notedb.ChangeNotes; import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.OrmException;
import com.google.inject.Singleton; import com.google.inject.Singleton;
import java.io.IOException; import java.io.IOException;
@@ -31,8 +30,7 @@ public class GetHashtags implements RestReadView<ChangeResource> {
@Override @Override
public Response<Set<String>> apply(ChangeResource req) public Response<Set<String>> apply(ChangeResource req)
throws AuthException, OrmException, IOException, BadRequestException { throws AuthException, OrmException, IOException, BadRequestException {
ChangeControl control = req.getControl(); ChangeNotes notes = req.getNotes().load();
ChangeNotes notes = control.getNotes().load();
Set<String> hashtags = notes.getHashtags(); Set<String> hashtags = notes.getHashtags();
if (hashtags == null) { if (hashtags == null) {
hashtags = Collections.emptySet(); hashtags = Collections.emptySet();

View File

@@ -40,7 +40,7 @@ public class GetPastAssignees implements RestReadView<ChangeResource> {
@Override @Override
public Response<List<AccountInfo>> apply(ChangeResource rsrc) throws OrmException { public Response<List<AccountInfo>> apply(ChangeResource rsrc) throws OrmException {
Set<Account.Id> pastAssignees = rsrc.getControl().getNotes().load().getPastAssignees(); Set<Account.Id> pastAssignees = rsrc.getNotes().load().getPastAssignees();
if (pastAssignees == null) { if (pastAssignees == null) {
return Response.ok(Collections.emptyList()); return Response.ok(Collections.emptyList());
} }

View File

@@ -49,7 +49,7 @@ public class ListChangeComments implements RestReadView<ChangeResource> {
@Override @Override
public Map<String, List<CommentInfo>> apply(ChangeResource rsrc) public Map<String, List<CommentInfo>> apply(ChangeResource rsrc)
throws AuthException, OrmException { throws AuthException, OrmException {
ChangeData cd = changeDataFactory.create(db.get(), rsrc.getControl()); ChangeData cd = changeDataFactory.create(db.get(), rsrc.getNotes());
return commentJson return commentJson
.get() .get()
.setFillAccounts(true) .setFillAccounts(true)

View File

@@ -50,13 +50,12 @@ public class ListChangeDrafts implements RestReadView<ChangeResource> {
@Override @Override
public Map<String, List<CommentInfo>> apply(ChangeResource rsrc) public Map<String, List<CommentInfo>> apply(ChangeResource rsrc)
throws AuthException, OrmException { throws AuthException, OrmException {
if (!rsrc.getControl().getUser().isIdentifiedUser()) { if (!rsrc.getUser().isIdentifiedUser()) {
throw new AuthException("Authentication required"); throw new AuthException("Authentication required");
} }
ChangeData cd = changeDataFactory.create(db.get(), rsrc.getControl()); ChangeData cd = changeDataFactory.create(db.get(), rsrc.getNotes());
List<Comment> drafts = List<Comment> drafts =
commentsUtil.draftByChangeAuthor( commentsUtil.draftByChangeAuthor(db.get(), cd.notes(), rsrc.getUser().getAccountId());
db.get(), cd.notes(), rsrc.getControl().getUser().getAccountId());
return commentJson return commentJson
.get() .get()
.setFillAccounts(false) .setFillAccounts(false)

View File

@@ -47,7 +47,7 @@ public class ListChangeRobotComments implements RestReadView<ChangeResource> {
@Override @Override
public Map<String, List<RobotCommentInfo>> apply(ChangeResource rsrc) public Map<String, List<RobotCommentInfo>> apply(ChangeResource rsrc)
throws AuthException, OrmException { throws AuthException, OrmException {
ChangeData cd = changeDataFactory.create(db.get(), rsrc.getControl()); ChangeData cd = changeDataFactory.create(db.get(), rsrc.getNotes());
return commentJson return commentJson
.get() .get()
.setFillAccounts(true) .setFillAccounts(true)

View File

@@ -98,7 +98,7 @@ public class Move extends RetryingRestModifyView<ChangeResource, MoveInput, Chan
throws RestApiException, OrmException, UpdateException, PermissionBackendException { throws RestApiException, OrmException, UpdateException, PermissionBackendException {
Change change = rsrc.getChange(); Change change = rsrc.getChange();
Project.NameKey project = rsrc.getProject(); Project.NameKey project = rsrc.getProject();
IdentifiedUser caller = rsrc.getUser(); IdentifiedUser caller = rsrc.getUser().asIdentifiedUser();
input.destinationBranch = RefNames.fullName(input.destinationBranch); input.destinationBranch = RefNames.fullName(input.destinationBranch);
if (change.getStatus().isClosed()) { if (change.getStatus().isClosed()) {

View File

@@ -55,7 +55,7 @@ public class PostHashtags
try (BatchUpdate bu = try (BatchUpdate bu =
updateFactory.create( updateFactory.create(
db.get(), req.getChange().getProject(), req.getControl().getUser(), TimeUtil.nowTs())) { db.get(), req.getChange().getProject(), req.getUser(), TimeUtil.nowTs())) {
SetHashtagsOp op = hashtagsFactory.create(input); SetHashtagsOp op = hashtagsFactory.create(input);
bu.addOp(req.getId(), op); bu.addOp(req.getId(), op);
bu.execute(); bu.execute();

View File

@@ -28,7 +28,6 @@ import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ChangeMessagesUtil; import com.google.gerrit.server.ChangeMessagesUtil;
import com.google.gerrit.server.permissions.GlobalPermission; import com.google.gerrit.server.permissions.GlobalPermission;
import com.google.gerrit.server.permissions.PermissionBackend; import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.update.BatchUpdate; import com.google.gerrit.server.update.BatchUpdate;
import com.google.gerrit.server.update.RetryHelper; import com.google.gerrit.server.update.RetryHelper;
import com.google.gerrit.server.update.RetryingRestModifyView; import com.google.gerrit.server.update.RetryingRestModifyView;
@@ -69,15 +68,11 @@ public class PostPrivate
return Response.ok(""); return Response.ok("");
} }
ChangeControl control = rsrc.getControl();
SetPrivateOp op = new SetPrivateOp(cmUtil, true, input); SetPrivateOp op = new SetPrivateOp(cmUtil, true, input);
try (BatchUpdate u = try (BatchUpdate u =
updateFactory.create( updateFactory.create(
dbProvider.get(), dbProvider.get(), rsrc.getProject(), rsrc.getUser(), TimeUtil.nowTs())) {
control.getProject().getNameKey(), u.addOp(rsrc.getId(), op).execute();
control.getUser(),
TimeUtil.nowTs())) {
u.addOp(control.getId(), op).execute();
} }
return Response.created(""); return Response.created("");

View File

@@ -60,7 +60,6 @@ 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.permissions.RefPermission; import com.google.gerrit.server.permissions.RefPermission;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.NoSuchProjectException; import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectCache; import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.query.change.ChangeData; import com.google.gerrit.server.query.change.ChangeData;
@@ -286,13 +285,12 @@ public class PostReviewers
} }
Set<Account.Id> reviewers = new HashSet<>(); Set<Account.Id> reviewers = new HashSet<>();
ChangeControl control = rsrc.getControl();
Set<Account> members; Set<Account> members;
try { try {
members = members =
groupMembersFactory groupMembersFactory
.create(control.getUser()) .create(rsrc.getUser())
.listAccounts(group.getGroupUUID(), control.getProject().getNameKey()); .listAccounts(group.getGroupUUID(), rsrc.getProject());
} catch (NoSuchGroupException e) { } catch (NoSuchGroupException e) {
return fail( return fail(
reviewer, reviewer,
@@ -424,7 +422,7 @@ public class PostReviewers
this.reviewersByEmail = reviewersByEmail == null ? ImmutableList.of() : reviewersByEmail; this.reviewersByEmail = reviewersByEmail == null ? ImmutableList.of() : reviewersByEmail;
this.state = state; this.state = state;
notes = rsrc.getNotes(); notes = rsrc.getNotes();
caller = rsrc.getUser(); caller = rsrc.getUser().asIdentifiedUser();
op = op =
postReviewersOpFactory.create( postReviewersOpFactory.create(
rsrc, this.reviewers, this.reviewersByEmail, state, notify, accountsToNotify); rsrc, this.reviewers, this.reviewersByEmail, state, notify, accountsToNotify);

View File

@@ -89,7 +89,7 @@ public class PublishChangeEdit
throws IOException, OrmException, RestApiException, UpdateException, throws IOException, OrmException, RestApiException, UpdateException,
ConfigInvalidException { ConfigInvalidException {
CreateChange.checkValidCLA(rsrc.getControl().getProjectControl()); CreateChange.checkValidCLA(rsrc.getControl().getProjectControl());
Optional<ChangeEdit> edit = editUtil.byChange(rsrc.getChange()); Optional<ChangeEdit> edit = editUtil.byChange(rsrc.getNotes(), rsrc.getUser());
if (!edit.isPresent()) { if (!edit.isPresent()) {
throw new ResourceConflictException( throw new ResourceConflictException(
String.format("no edit exists for change %s", rsrc.getChange().getChangeId())); String.format("no edit exists for change %s", rsrc.getChange().getChangeId()));

View File

@@ -155,7 +155,7 @@ public class PublishDraftPatchSet
throws RestApiException, UpdateException { throws RestApiException, UpdateException {
return publish.apply( return publish.apply(
updateFactory, updateFactory,
rsrc.getControl().getUser(), rsrc.getUser(),
rsrc.getChange(), rsrc.getChange(),
rsrc.getChange().currentPatchSetId(), rsrc.getChange().currentPatchSetId(),
null); null);

View File

@@ -94,10 +94,7 @@ public class PutAssignee extends RetryingRestModifyView<ChangeResource, Assignee
try (BatchUpdate bu = try (BatchUpdate bu =
updateFactory.create( updateFactory.create(
db.get(), db.get(), rsrc.getChange().getProject(), rsrc.getUser(), TimeUtil.nowTs())) {
rsrc.getChange().getProject(),
rsrc.getControl().getUser(),
TimeUtil.nowTs())) {
SetAssigneeOp op = assigneeFactory.create(assignee); SetAssigneeOp op = assigneeFactory.create(assignee);
bu.addOp(rsrc.getId(), op); bu.addOp(rsrc.getId(), op);

View File

@@ -110,7 +110,7 @@ public class PutMessage
} }
String sanitizedCommitMessage = CommitMessageUtil.checkAndSanitizeCommitMessage(input.message); String sanitizedCommitMessage = CommitMessageUtil.checkAndSanitizeCommitMessage(input.message);
ensureCanEditCommitMessage(resource.getControl().getNotes()); ensureCanEditCommitMessage(resource.getNotes());
ensureChangeIdIsCorrect( ensureChangeIdIsCorrect(
resource.getControl().getProjectControl().getProjectState().isRequireChangeID(), resource.getControl().getProjectControl().getProjectState().isRequireChangeID(),
resource.getChange().getKey().get(), resource.getChange().getKey().get(),

View File

@@ -87,7 +87,7 @@ public class RebaseChangeEdit
PermissionBackendException { PermissionBackendException {
Project.NameKey project = rsrc.getProject(); Project.NameKey project = rsrc.getProject();
try (Repository repository = repositoryManager.openRepository(project)) { try (Repository repository = repositoryManager.openRepository(project)) {
editModifier.rebaseEdit(repository, rsrc.getControl()); editModifier.rebaseEdit(repository, rsrc.getNotes());
} catch (InvalidChangeOperationException e) { } catch (InvalidChangeOperationException e) {
throw new ResourceConflictException(e.getMessage()); throw new ResourceConflictException(e.getMessage());
} }

View File

@@ -37,7 +37,6 @@ import com.google.gerrit.server.mail.send.RestoredSender;
import com.google.gerrit.server.notedb.ChangeUpdate; import com.google.gerrit.server.notedb.ChangeUpdate;
import com.google.gerrit.server.permissions.ChangePermission; import com.google.gerrit.server.permissions.ChangePermission;
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.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;
@@ -88,11 +87,10 @@ public class Restore extends RetryingRestModifyView<ChangeResource, RestoreInput
throws RestApiException, UpdateException, OrmException, PermissionBackendException { throws RestApiException, UpdateException, OrmException, PermissionBackendException {
req.permissions().database(dbProvider).check(ChangePermission.RESTORE); req.permissions().database(dbProvider).check(ChangePermission.RESTORE);
ChangeControl ctl = req.getControl();
Op op = new Op(input); Op op = new Op(input);
try (BatchUpdate u = try (BatchUpdate u =
updateFactory.create( updateFactory.create(
dbProvider.get(), req.getChange().getProject(), ctl.getUser(), TimeUtil.nowTs())) { dbProvider.get(), req.getChange().getProject(), req.getUser(), TimeUtil.nowTs())) {
u.addOp(req.getId(), op).execute(); u.addOp(req.getId(), op).execute();
} }
return json.noOptions().format(op.change); return json.noOptions().format(op.change);

View File

@@ -42,10 +42,10 @@ import com.google.gerrit.server.Sequences;
import com.google.gerrit.server.extensions.events.ChangeReverted; import com.google.gerrit.server.extensions.events.ChangeReverted;
import com.google.gerrit.server.git.GitRepositoryManager; import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.mail.send.RevertedSender; import com.google.gerrit.server.mail.send.RevertedSender;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.notedb.ReviewerStateInternal; import com.google.gerrit.server.notedb.ReviewerStateInternal;
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.update.BatchUpdate; import com.google.gerrit.server.update.BatchUpdate;
import com.google.gerrit.server.update.BatchUpdateOp; import com.google.gerrit.server.update.BatchUpdateOp;
@@ -83,7 +83,6 @@ public class Revert extends RetryingRestModifyView<ChangeResource, RevertInput,
private final Provider<ReviewDb> db; private final Provider<ReviewDb> db;
private final PermissionBackend permissionBackend; private final PermissionBackend permissionBackend;
private final Provider<CurrentUser> user;
private final GitRepositoryManager repoManager; private final GitRepositoryManager repoManager;
private final ChangeInserter.Factory changeInserterFactory; private final ChangeInserter.Factory changeInserterFactory;
private final ChangeMessagesUtil cmUtil; private final ChangeMessagesUtil cmUtil;
@@ -99,7 +98,6 @@ public class Revert extends RetryingRestModifyView<ChangeResource, RevertInput,
Revert( Revert(
Provider<ReviewDb> db, Provider<ReviewDb> db,
PermissionBackend permissionBackend, PermissionBackend permissionBackend,
Provider<CurrentUser> user,
GitRepositoryManager repoManager, GitRepositoryManager repoManager,
ChangeInserter.Factory changeInserterFactory, ChangeInserter.Factory changeInserterFactory,
ChangeMessagesUtil cmUtil, ChangeMessagesUtil cmUtil,
@@ -114,7 +112,6 @@ public class Revert extends RetryingRestModifyView<ChangeResource, RevertInput,
super(retryHelper); super(retryHelper);
this.db = db; this.db = db;
this.permissionBackend = permissionBackend; this.permissionBackend = permissionBackend;
this.user = user;
this.repoManager = repoManager; this.repoManager = repoManager;
this.changeInserterFactory = changeInserterFactory; this.changeInserterFactory = changeInserterFactory;
this.cmUtil = cmUtil; this.cmUtil = cmUtil;
@@ -138,24 +135,24 @@ public class Revert extends RetryingRestModifyView<ChangeResource, RevertInput,
} }
CreateChange.checkValidCLA(rsrc.getControl().getProjectControl()); CreateChange.checkValidCLA(rsrc.getControl().getProjectControl());
permissionBackend.user(user).ref(change.getDest()).check(CREATE_CHANGE); permissionBackend.user(rsrc.getUser()).ref(change.getDest()).check(CREATE_CHANGE);
Change.Id revertId = Change.Id revertId =
revert(updateFactory, rsrc.getControl(), Strings.emptyToNull(input.message)); revert(updateFactory, rsrc.getNotes(), rsrc.getUser(), Strings.emptyToNull(input.message));
return json.noOptions().format(rsrc.getProject(), revertId); return json.noOptions().format(rsrc.getProject(), revertId);
} }
private Change.Id revert(BatchUpdate.Factory updateFactory, ChangeControl ctl, String message) private Change.Id revert(
BatchUpdate.Factory updateFactory, ChangeNotes notes, CurrentUser user, String message)
throws OrmException, IOException, RestApiException, UpdateException { throws OrmException, IOException, RestApiException, UpdateException {
Change.Id changeIdToRevert = ctl.getChange().getId(); Change.Id changeIdToRevert = notes.getChangeId();
PatchSet.Id patchSetId = ctl.getChange().currentPatchSetId(); PatchSet.Id patchSetId = notes.getChange().currentPatchSetId();
PatchSet patch = psUtil.get(db.get(), ctl.getNotes(), patchSetId); PatchSet patch = psUtil.get(db.get(), notes, patchSetId);
if (patch == null) { if (patch == null) {
throw new ResourceNotFoundException(changeIdToRevert.toString()); throw new ResourceNotFoundException(changeIdToRevert.toString());
} }
Project.NameKey project = ctl.getProject().getNameKey(); Project.NameKey project = notes.getProjectName();
CurrentUser user = ctl.getUser();
try (Repository git = repoManager.openRepository(project); try (Repository git = repoManager.openRepository(project);
ObjectInserter oi = git.newObjectInserter(); ObjectInserter oi = git.newObjectInserter();
ObjectReader reader = oi.newReader(); ObjectReader reader = oi.newReader();
@@ -180,7 +177,7 @@ public class Revert extends RetryingRestModifyView<ChangeResource, RevertInput,
revertCommitBuilder.setAuthor(authorIdent); revertCommitBuilder.setAuthor(authorIdent);
revertCommitBuilder.setCommitter(authorIdent); revertCommitBuilder.setCommitter(authorIdent);
Change changeToRevert = ctl.getChange(); Change changeToRevert = notes.getChange();
if (message == null) { if (message == null) {
message = message =
MessageFormat.format( MessageFormat.format(
@@ -204,11 +201,11 @@ public class Revert extends RetryingRestModifyView<ChangeResource, RevertInput,
ChangeInserter ins = ChangeInserter ins =
changeInserterFactory changeInserterFactory
.create(changeId, revertCommit, ctl.getChange().getDest().get()) .create(changeId, revertCommit, notes.getChange().getDest().get())
.setTopic(changeToRevert.getTopic()); .setTopic(changeToRevert.getTopic());
ins.setMessage("Uploaded patch set 1."); ins.setMessage("Uploaded patch set 1.");
ReviewerSet reviewerSet = approvalsUtil.getReviewers(db.get(), ctl.getNotes()); ReviewerSet reviewerSet = approvalsUtil.getReviewers(db.get(), notes);
Set<Account.Id> reviewers = new HashSet<>(); Set<Account.Id> reviewers = new HashSet<>();
reviewers.add(changeToRevert.getOwner()); reviewers.add(changeToRevert.getOwner());
@@ -224,7 +221,7 @@ public class Revert extends RetryingRestModifyView<ChangeResource, RevertInput,
try (BatchUpdate bu = updateFactory.create(db.get(), project, user, now)) { try (BatchUpdate bu = updateFactory.create(db.get(), project, user, now)) {
bu.setRepository(git, revWalk, oi); bu.setRepository(git, revWalk, oi);
bu.insertChange(ins); bu.insertChange(ins);
bu.addOp(changeId, new NotifyOp(ctl.getChange(), ins)); bu.addOp(changeId, new NotifyOp(notes.getChange(), ins));
bu.addOp(changeToRevert.getId(), new PostRevertedMessageOp(computedChangeId)); bu.addOp(changeToRevert.getId(), new PostRevertedMessageOp(computedChangeId));
bu.execute(); bu.execute();
} }
@@ -243,7 +240,10 @@ public class Revert extends RetryingRestModifyView<ChangeResource, RevertInput,
.setVisible( .setVisible(
and( and(
change.getStatus() == Change.Status.MERGED, change.getStatus() == Change.Status.MERGED,
permissionBackend.user(user).ref(change.getDest()).testCond(CREATE_CHANGE))); permissionBackend
.user(rsrc.getUser())
.ref(change.getDest())
.testCond(CREATE_CHANGE)));
} }
private class NotifyOp implements BatchUpdateOp { private class NotifyOp implements BatchUpdateOp {

View File

@@ -140,8 +140,8 @@ public class Revisions implements ChildCollection<ChangeResource, RevisionResour
} }
private List<RevisionResource> loadEdit(ChangeResource change, RevId revid) private List<RevisionResource> loadEdit(ChangeResource change, RevId revid)
throws AuthException, IOException, OrmException { throws AuthException, IOException {
Optional<ChangeEdit> edit = editUtil.byChange(change.getChange()); Optional<ChangeEdit> edit = editUtil.byChange(change.getNotes(), change.getUser());
if (edit.isPresent()) { if (edit.isPresent()) {
PatchSet ps = new PatchSet(new PatchSet.Id(change.getId(), 0)); PatchSet ps = new PatchSet(new PatchSet.Id(change.getId(), 0));
RevId editRevId = new RevId(ObjectId.toString(edit.get().getEditCommit())); RevId editRevId = new RevId(ObjectId.toString(edit.get().getEditCommit()));

View File

@@ -125,9 +125,7 @@ public class SubmittedTogether implements RestReadView<ChangeResource> {
if (c.getStatus().isOpen()) { if (c.getStatus().isOpen()) {
ChangeSet cs = ChangeSet cs =
mergeSuperSet mergeSuperSet.get().completeChangeSet(dbProvider.get(), c, resource.getUser());
.get()
.completeChangeSet(dbProvider.get(), c, resource.getControl().getUser());
cds = cs.changes().asList(); cds = cs.changes().asList();
hidden = cs.nonVisibleChanges().size(); hidden = cs.nonVisibleChanges().size();
} else if (c.getStatus().asChangeStatus() == ChangeStatus.MERGED) { } else if (c.getStatus().asChangeStatus() == ChangeStatus.MERGED) {

View File

@@ -35,10 +35,10 @@ import com.google.gerrit.server.edit.tree.RestoreFileModification;
import com.google.gerrit.server.edit.tree.TreeCreator; import com.google.gerrit.server.edit.tree.TreeCreator;
import com.google.gerrit.server.edit.tree.TreeModification; import com.google.gerrit.server.edit.tree.TreeModification;
import com.google.gerrit.server.index.change.ChangeIndexer; import com.google.gerrit.server.index.change.ChangeIndexer;
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.project.ChangeControl;
import com.google.gerrit.server.project.InvalidChangeOperationException; import com.google.gerrit.server.project.InvalidChangeOperationException;
import com.google.gerrit.server.util.CommitMessageUtil; import com.google.gerrit.server.util.CommitMessageUtil;
import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.OrmException;
@@ -106,34 +106,32 @@ public class ChangeEditModifier {
* Creates a new change edit. * Creates a new change edit.
* *
* @param repository the affected Git repository * @param repository the affected Git repository
* @param changeControl the {@code ChangeControl} of the change for which the change edit should * @param notes the {@link ChangeNotes} of the change for which the change edit should be created
* be created
* @throws AuthException if the user isn't authenticated or not allowed to use change edits * @throws AuthException if the user isn't authenticated or not allowed to use change edits
* @throws InvalidChangeOperationException if a change edit already existed for the change * @throws InvalidChangeOperationException if a change edit already existed for the change
* @throws PermissionBackendException * @throws PermissionBackendException
*/ */
public void createEdit(Repository repository, ChangeControl changeControl) public void createEdit(Repository repository, ChangeNotes notes)
throws AuthException, IOException, InvalidChangeOperationException, OrmException, throws AuthException, IOException, InvalidChangeOperationException, OrmException,
PermissionBackendException { PermissionBackendException {
assertCanEdit(changeControl); assertCanEdit(notes);
Optional<ChangeEdit> changeEdit = lookupChangeEdit(changeControl); Optional<ChangeEdit> changeEdit = lookupChangeEdit(notes);
if (changeEdit.isPresent()) { if (changeEdit.isPresent()) {
throw new InvalidChangeOperationException( throw new InvalidChangeOperationException(
String.format("A change edit already exists for change %s", changeControl.getId())); String.format("A change edit already exists for change %s", notes.getChangeId()));
} }
PatchSet currentPatchSet = lookupCurrentPatchSet(changeControl); PatchSet currentPatchSet = lookupCurrentPatchSet(notes);
ObjectId patchSetCommitId = getPatchSetCommitId(currentPatchSet); ObjectId patchSetCommitId = getPatchSetCommitId(currentPatchSet);
createEdit(repository, changeControl, currentPatchSet, patchSetCommitId, TimeUtil.nowTs()); createEdit(repository, notes, currentPatchSet, patchSetCommitId, TimeUtil.nowTs());
} }
/** /**
* Rebase change edit on latest patch set * Rebase change edit on latest patch set
* *
* @param repository the affected Git repository * @param repository the affected Git repository
* @param changeControl the {@code ChangeControl} of the change whose change edit should be * @param notes the {@link ChangeNotes} of the change whose change edit should be rebased
* rebased
* @throws AuthException if the user isn't authenticated or not allowed to use change edits * @throws AuthException if the user isn't authenticated or not allowed to use change edits
* @throws InvalidChangeOperationException if a change edit doesn't exist for the specified * @throws InvalidChangeOperationException if a change edit doesn't exist for the specified
* change, the change edit is already based on the latest patch set, or the change represents * change, the change edit is already based on the latest patch set, or the change represents
@@ -141,24 +139,24 @@ public class ChangeEditModifier {
* @throws MergeConflictException if rebase fails due to merge conflicts * @throws MergeConflictException if rebase fails due to merge conflicts
* @throws PermissionBackendException * @throws PermissionBackendException
*/ */
public void rebaseEdit(Repository repository, ChangeControl changeControl) public void rebaseEdit(Repository repository, ChangeNotes notes)
throws AuthException, InvalidChangeOperationException, IOException, OrmException, throws AuthException, InvalidChangeOperationException, IOException, OrmException,
MergeConflictException, PermissionBackendException { MergeConflictException, PermissionBackendException {
assertCanEdit(changeControl); assertCanEdit(notes);
Optional<ChangeEdit> optionalChangeEdit = lookupChangeEdit(changeControl); Optional<ChangeEdit> optionalChangeEdit = lookupChangeEdit(notes);
if (!optionalChangeEdit.isPresent()) { if (!optionalChangeEdit.isPresent()) {
throw new InvalidChangeOperationException( throw new InvalidChangeOperationException(
String.format("No change edit exists for change %s", changeControl.getId())); String.format("No change edit exists for change %s", notes.getChangeId()));
} }
ChangeEdit changeEdit = optionalChangeEdit.get(); ChangeEdit changeEdit = optionalChangeEdit.get();
PatchSet currentPatchSet = lookupCurrentPatchSet(changeControl); PatchSet currentPatchSet = lookupCurrentPatchSet(notes);
if (isBasedOn(changeEdit, currentPatchSet)) { if (isBasedOn(changeEdit, currentPatchSet)) {
throw new InvalidChangeOperationException( throw new InvalidChangeOperationException(
String.format( String.format(
"Change edit for change %s is already based on latest patch set %s", "Change edit for change %s is already based on latest patch set %s",
changeControl.getId(), currentPatchSet.getId())); notes.getChangeId(), currentPatchSet.getId()));
} }
rebase(repository, changeEdit, currentPatchSet); rebase(repository, changeEdit, currentPatchSet);
@@ -198,23 +196,22 @@ public class ChangeEditModifier {
* be created based on the current patch set. * be created based on the current patch set.
* *
* @param repository the affected Git repository * @param repository the affected Git repository
* @param changeControl the {@code ChangeControl} of the change whose change edit's message should * @param notes the {@link ChangeNotes} of the change whose change edit's message should be
* be modified * modified
* @param newCommitMessage the new commit message * @param newCommitMessage the new commit message
* @throws AuthException if the user isn't authenticated or not allowed to use change edits * @throws AuthException if the user isn't authenticated or not allowed to use change edits
* @throws UnchangedCommitMessageException if the commit message is the same as before * @throws UnchangedCommitMessageException if the commit message is the same as before
* @throws PermissionBackendException * @throws PermissionBackendException
* @throws BadRequestException if the commit message is malformed * @throws BadRequestException if the commit message is malformed
*/ */
public void modifyMessage( public void modifyMessage(Repository repository, ChangeNotes notes, String newCommitMessage)
Repository repository, ChangeControl changeControl, String newCommitMessage)
throws AuthException, IOException, UnchangedCommitMessageException, OrmException, throws AuthException, IOException, UnchangedCommitMessageException, OrmException,
PermissionBackendException, BadRequestException { PermissionBackendException, BadRequestException {
assertCanEdit(changeControl); assertCanEdit(notes);
newCommitMessage = CommitMessageUtil.checkAndSanitizeCommitMessage(newCommitMessage); newCommitMessage = CommitMessageUtil.checkAndSanitizeCommitMessage(newCommitMessage);
Optional<ChangeEdit> optionalChangeEdit = lookupChangeEdit(changeControl); Optional<ChangeEdit> optionalChangeEdit = lookupChangeEdit(notes);
PatchSet basePatchSet = getBasePatchSet(optionalChangeEdit, changeControl); PatchSet basePatchSet = getBasePatchSet(optionalChangeEdit, notes);
RevCommit basePatchSetCommit = lookupCommit(repository, basePatchSet); RevCommit basePatchSetCommit = lookupCommit(repository, basePatchSet);
RevCommit baseCommit = RevCommit baseCommit =
optionalChangeEdit.map(ChangeEdit::getEditCommit).orElse(basePatchSetCommit); optionalChangeEdit.map(ChangeEdit::getEditCommit).orElse(basePatchSetCommit);
@@ -232,7 +229,7 @@ public class ChangeEditModifier {
if (optionalChangeEdit.isPresent()) { if (optionalChangeEdit.isPresent()) {
updateEdit(repository, optionalChangeEdit.get(), newEditCommit, nowTimestamp); updateEdit(repository, optionalChangeEdit.get(), newEditCommit, nowTimestamp);
} else { } else {
createEdit(repository, changeControl, basePatchSet, newEditCommit, nowTimestamp); createEdit(repository, notes, basePatchSet, newEditCommit, nowTimestamp);
} }
} }
@@ -241,8 +238,7 @@ public class ChangeEditModifier {
* will be created based on the current patch set. * will be created based on the current patch set.
* *
* @param repository the affected Git repository * @param repository the affected Git repository
* @param changeControl the {@code ChangeControl} of the change whose change edit should be * @param notes the {@link ChangeNotes} of the change whose change edit should be modified
* modified
* @param filePath the path of the file whose contents should be modified * @param filePath the path of the file whose contents should be modified
* @param newContent the new file content * @param newContent the new file content
* @throws AuthException if the user isn't authenticated or not allowed to use change edits * @throws AuthException if the user isn't authenticated or not allowed to use change edits
@@ -250,10 +246,10 @@ public class ChangeEditModifier {
* @throws PermissionBackendException * @throws PermissionBackendException
*/ */
public void modifyFile( public void modifyFile(
Repository repository, ChangeControl changeControl, String filePath, RawInput newContent) Repository repository, ChangeNotes notes, String filePath, RawInput newContent)
throws AuthException, InvalidChangeOperationException, IOException, OrmException, throws AuthException, InvalidChangeOperationException, IOException, OrmException,
PermissionBackendException { PermissionBackendException {
modifyTree(repository, changeControl, new ChangeFileContentModification(filePath, newContent)); modifyTree(repository, notes, new ChangeFileContentModification(filePath, newContent));
} }
/** /**
@@ -261,17 +257,16 @@ public class ChangeEditModifier {
* will be created based on the current patch set. * will be created based on the current patch set.
* *
* @param repository the affected Git repository * @param repository the affected Git repository
* @param changeControl the {@code ChangeControl} of the change whose change edit should be * @param notes the {@link ChangeNotes} of the change whose change edit should be modified
* modified
* @param file path of the file which should be deleted * @param file path of the file which should be deleted
* @throws AuthException if the user isn't authenticated or not allowed to use change edits * @throws AuthException if the user isn't authenticated or not allowed to use change edits
* @throws InvalidChangeOperationException if the file does not exist * @throws InvalidChangeOperationException if the file does not exist
* @throws PermissionBackendException * @throws PermissionBackendException
*/ */
public void deleteFile(Repository repository, ChangeControl changeControl, String file) public void deleteFile(Repository repository, ChangeNotes notes, String file)
throws AuthException, InvalidChangeOperationException, IOException, OrmException, throws AuthException, InvalidChangeOperationException, IOException, OrmException,
PermissionBackendException { PermissionBackendException {
modifyTree(repository, changeControl, new DeleteFileModification(file)); modifyTree(repository, notes, new DeleteFileModification(file));
} }
/** /**
@@ -279,8 +274,7 @@ public class ChangeEditModifier {
* exist, a new one will be created based on the current patch set. * exist, a new one will be created based on the current patch set.
* *
* @param repository the affected Git repository * @param repository the affected Git repository
* @param changeControl the {@code ChangeControl} of the change whose change edit should be * @param notes the {@link ChangeNotes} of the change whose change edit should be modified
* modified
* @param currentFilePath the current path/name of the file * @param currentFilePath the current path/name of the file
* @param newFilePath the desired path/name of the file * @param newFilePath the desired path/name of the file
* @throws AuthException if the user isn't authenticated or not allowed to use change edits * @throws AuthException if the user isn't authenticated or not allowed to use change edits
@@ -289,13 +283,10 @@ public class ChangeEditModifier {
* @throws PermissionBackendException * @throws PermissionBackendException
*/ */
public void renameFile( public void renameFile(
Repository repository, Repository repository, ChangeNotes notes, String currentFilePath, String newFilePath)
ChangeControl changeControl,
String currentFilePath,
String newFilePath)
throws AuthException, InvalidChangeOperationException, IOException, OrmException, throws AuthException, InvalidChangeOperationException, IOException, OrmException,
PermissionBackendException { PermissionBackendException {
modifyTree(repository, changeControl, new RenameFileModification(currentFilePath, newFilePath)); modifyTree(repository, notes, new RenameFileModification(currentFilePath, newFilePath));
} }
/** /**
@@ -304,27 +295,26 @@ public class ChangeEditModifier {
* current patch set. * current patch set.
* *
* @param repository the affected Git repository * @param repository the affected Git repository
* @param changeControl the {@code ChangeControl} of the change whose change edit should be * @param notes the {@link ChangeNotes} of the change whose change edit should be modified
* modified
* @param file the path of the file which should be restored * @param file the path of the file which should be restored
* @throws AuthException if the user isn't authenticated or not allowed to use change edits * @throws AuthException if the user isn't authenticated or not allowed to use change edits
* @throws InvalidChangeOperationException if the file was already restored * @throws InvalidChangeOperationException if the file was already restored
* @throws PermissionBackendException * @throws PermissionBackendException
*/ */
public void restoreFile(Repository repository, ChangeControl changeControl, String file) public void restoreFile(Repository repository, ChangeNotes notes, String file)
throws AuthException, InvalidChangeOperationException, IOException, OrmException, throws AuthException, InvalidChangeOperationException, IOException, OrmException,
PermissionBackendException { PermissionBackendException {
modifyTree(repository, changeControl, new RestoreFileModification(file)); modifyTree(repository, notes, new RestoreFileModification(file));
} }
private void modifyTree( private void modifyTree(
Repository repository, ChangeControl changeControl, TreeModification treeModification) Repository repository, ChangeNotes notes, TreeModification treeModification)
throws AuthException, IOException, OrmException, InvalidChangeOperationException, throws AuthException, IOException, OrmException, InvalidChangeOperationException,
PermissionBackendException { PermissionBackendException {
assertCanEdit(changeControl); assertCanEdit(notes);
Optional<ChangeEdit> optionalChangeEdit = lookupChangeEdit(changeControl); Optional<ChangeEdit> optionalChangeEdit = lookupChangeEdit(notes);
PatchSet basePatchSet = getBasePatchSet(optionalChangeEdit, changeControl); PatchSet basePatchSet = getBasePatchSet(optionalChangeEdit, notes);
RevCommit basePatchSetCommit = lookupCommit(repository, basePatchSet); RevCommit basePatchSetCommit = lookupCommit(repository, basePatchSet);
RevCommit baseCommit = RevCommit baseCommit =
optionalChangeEdit.map(ChangeEdit::getEditCommit).orElse(basePatchSetCommit); optionalChangeEdit.map(ChangeEdit::getEditCommit).orElse(basePatchSetCommit);
@@ -339,7 +329,7 @@ public class ChangeEditModifier {
if (optionalChangeEdit.isPresent()) { if (optionalChangeEdit.isPresent()) {
updateEdit(repository, optionalChangeEdit.get(), newEditCommit, nowTimestamp); updateEdit(repository, optionalChangeEdit.get(), newEditCommit, nowTimestamp);
} else { } else {
createEdit(repository, changeControl, basePatchSet, newEditCommit, nowTimestamp); createEdit(repository, notes, basePatchSet, newEditCommit, nowTimestamp);
} }
} }
@@ -349,7 +339,7 @@ public class ChangeEditModifier {
* change edit doesn't exist, a new one will be created. * change edit doesn't exist, a new one will be created.
* *
* @param repository the affected Git repository * @param repository the affected Git repository
* @param changeControl the {@code ChangeControl} of the change to which the patch set belongs * @param notes the {@link ChangeNotes} of the change to which the patch set belongs
* @param patchSet the {@code PatchSet} which should be modified * @param patchSet the {@code PatchSet} which should be modified
* @param treeModifications the modifications which should be applied * @param treeModifications the modifications which should be applied
* @return the resulting {@code ChangeEdit} * @return the resulting {@code ChangeEdit}
@@ -361,15 +351,15 @@ public class ChangeEditModifier {
*/ */
public ChangeEdit combineWithModifiedPatchSetTree( public ChangeEdit combineWithModifiedPatchSetTree(
Repository repository, Repository repository,
ChangeControl changeControl, ChangeNotes notes,
PatchSet patchSet, PatchSet patchSet,
List<TreeModification> treeModifications) List<TreeModification> treeModifications)
throws AuthException, IOException, InvalidChangeOperationException, MergeConflictException, throws AuthException, IOException, InvalidChangeOperationException, MergeConflictException,
OrmException, PermissionBackendException { OrmException, PermissionBackendException {
assertCanEdit(changeControl); assertCanEdit(notes);
Optional<ChangeEdit> optionalChangeEdit = lookupChangeEdit(changeControl); Optional<ChangeEdit> optionalChangeEdit = lookupChangeEdit(notes);
ensureAllowedPatchSet(changeControl, optionalChangeEdit, patchSet); ensureAllowedPatchSet(notes, optionalChangeEdit, patchSet);
RevCommit patchSetCommit = lookupCommit(repository, patchSet); RevCommit patchSetCommit = lookupCommit(repository, patchSet);
ObjectId newTreeId = createNewTree(repository, patchSetCommit, treeModifications); ObjectId newTreeId = createNewTree(repository, patchSetCommit, treeModifications);
@@ -392,11 +382,10 @@ public class ChangeEditModifier {
if (optionalChangeEdit.isPresent()) { if (optionalChangeEdit.isPresent()) {
return updateEdit(repository, optionalChangeEdit.get(), newEditCommit, nowTimestamp); return updateEdit(repository, optionalChangeEdit.get(), newEditCommit, nowTimestamp);
} }
return createEdit(repository, changeControl, patchSet, newEditCommit, nowTimestamp); return createEdit(repository, notes, patchSet, newEditCommit, nowTimestamp);
} }
private void assertCanEdit(ChangeControl changeControl) private void assertCanEdit(ChangeNotes notes) throws AuthException, PermissionBackendException {
throws AuthException, PermissionBackendException {
if (!currentUser.get().isIdentifiedUser()) { if (!currentUser.get().isIdentifiedUser()) {
throw new AuthException("Authentication required"); throw new AuthException("Authentication required");
} }
@@ -404,7 +393,7 @@ public class ChangeEditModifier {
permissionBackend permissionBackend
.user(currentUser) .user(currentUser)
.database(reviewDb) .database(reviewDb)
.change(changeControl.getNotes()) .change(notes)
.check(ChangePermission.ADD_PATCH_SET); .check(ChangePermission.ADD_PATCH_SET);
} catch (AuthException denied) { } catch (AuthException denied) {
throw new AuthException("edit not permitted", denied); throw new AuthException("edit not permitted", denied);
@@ -412,7 +401,7 @@ public class ChangeEditModifier {
} }
private static void ensureAllowedPatchSet( private static void ensureAllowedPatchSet(
ChangeControl changeControl, Optional<ChangeEdit> optionalChangeEdit, PatchSet patchSet) ChangeNotes notes, Optional<ChangeEdit> optionalChangeEdit, PatchSet patchSet)
throws InvalidChangeOperationException { throws InvalidChangeOperationException {
if (optionalChangeEdit.isPresent()) { if (optionalChangeEdit.isPresent()) {
ChangeEdit changeEdit = optionalChangeEdit.get(); ChangeEdit changeEdit = optionalChangeEdit.get();
@@ -425,7 +414,7 @@ public class ChangeEditModifier {
} }
} else { } else {
PatchSet.Id patchSetId = patchSet.getId(); PatchSet.Id patchSetId = patchSet.getId();
PatchSet.Id currentPatchSetId = changeControl.getChange().currentPatchSetId(); PatchSet.Id currentPatchSetId = notes.getChange().currentPatchSetId();
if (!patchSetId.equals(currentPatchSetId)) { if (!patchSetId.equals(currentPatchSetId)) {
throw new InvalidChangeOperationException( throw new InvalidChangeOperationException(
String.format( String.format(
@@ -435,21 +424,19 @@ public class ChangeEditModifier {
} }
} }
private Optional<ChangeEdit> lookupChangeEdit(ChangeControl changeControl) private Optional<ChangeEdit> lookupChangeEdit(ChangeNotes notes)
throws AuthException, IOException { throws AuthException, IOException {
return changeEditUtil.byChange(changeControl); return changeEditUtil.byChange(notes);
} }
private PatchSet getBasePatchSet( private PatchSet getBasePatchSet(Optional<ChangeEdit> optionalChangeEdit, ChangeNotes notes)
Optional<ChangeEdit> optionalChangeEdit, ChangeControl changeControl) throws OrmException { throws OrmException {
Optional<PatchSet> editBasePatchSet = optionalChangeEdit.map(ChangeEdit::getBasePatchSet); Optional<PatchSet> editBasePatchSet = optionalChangeEdit.map(ChangeEdit::getBasePatchSet);
return editBasePatchSet.isPresent() return editBasePatchSet.isPresent() ? editBasePatchSet.get() : lookupCurrentPatchSet(notes);
? editBasePatchSet.get()
: lookupCurrentPatchSet(changeControl);
} }
private PatchSet lookupCurrentPatchSet(ChangeControl changeControl) throws OrmException { private PatchSet lookupCurrentPatchSet(ChangeNotes notes) throws OrmException {
return patchSetUtil.current(reviewDb.get(), changeControl.getNotes()); return patchSetUtil.current(reviewDb.get(), notes);
} }
private static boolean isBasedOn(ChangeEdit changeEdit, PatchSet patchSet) { private static boolean isBasedOn(ChangeEdit changeEdit, PatchSet patchSet) {
@@ -531,12 +518,12 @@ public class ChangeEditModifier {
private ChangeEdit createEdit( private ChangeEdit createEdit(
Repository repository, Repository repository,
ChangeControl changeControl, ChangeNotes notes,
PatchSet basePatchSet, PatchSet basePatchSet,
ObjectId newEditCommitId, ObjectId newEditCommitId,
Timestamp timestamp) Timestamp timestamp)
throws IOException, OrmException { throws IOException, OrmException {
Change change = changeControl.getChange(); Change change = notes.getChange();
String editRefName = getEditRefName(change, basePatchSet); String editRefName = getEditRefName(change, basePatchSet);
updateReference(repository, editRefName, ObjectId.zeroId(), newEditCommitId, timestamp); updateReference(repository, editRefName, ObjectId.zeroId(), newEditCommitId, timestamp);
reindex(change); reindex(change);

View File

@@ -38,8 +38,8 @@ import com.google.gerrit.server.change.ChangeKindCache;
import com.google.gerrit.server.change.PatchSetInserter; import com.google.gerrit.server.change.PatchSetInserter;
import com.google.gerrit.server.git.GitRepositoryManager; import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.index.change.ChangeIndexer; import com.google.gerrit.server.index.change.ChangeIndexer;
import com.google.gerrit.server.notedb.ChangeNotes;
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.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.RepoContext; import com.google.gerrit.server.update.RepoContext;
@@ -70,10 +70,9 @@ import org.eclipse.jgit.revwalk.RevWalk;
public class ChangeEditUtil { public class ChangeEditUtil {
private final GitRepositoryManager gitManager; private final GitRepositoryManager gitManager;
private final PatchSetInserter.Factory patchSetInserterFactory; private final PatchSetInserter.Factory patchSetInserterFactory;
private final ChangeControl.GenericFactory changeControlFactory;
private final ChangeIndexer indexer; private final ChangeIndexer indexer;
private final Provider<ReviewDb> db; private final Provider<ReviewDb> db;
private final Provider<CurrentUser> user; private final Provider<CurrentUser> userProvider;
private final ChangeKindCache changeKindCache; private final ChangeKindCache changeKindCache;
private final PatchSetUtil psUtil; private final PatchSetUtil psUtil;
@@ -81,40 +80,32 @@ public class ChangeEditUtil {
ChangeEditUtil( ChangeEditUtil(
GitRepositoryManager gitManager, GitRepositoryManager gitManager,
PatchSetInserter.Factory patchSetInserterFactory, PatchSetInserter.Factory patchSetInserterFactory,
ChangeControl.GenericFactory changeControlFactory,
ChangeIndexer indexer, ChangeIndexer indexer,
Provider<ReviewDb> db, Provider<ReviewDb> db,
Provider<CurrentUser> user, Provider<CurrentUser> userProvider,
ChangeKindCache changeKindCache, ChangeKindCache changeKindCache,
PatchSetUtil psUtil) { PatchSetUtil psUtil) {
this.gitManager = gitManager; this.gitManager = gitManager;
this.patchSetInserterFactory = patchSetInserterFactory; this.patchSetInserterFactory = patchSetInserterFactory;
this.changeControlFactory = changeControlFactory;
this.indexer = indexer; this.indexer = indexer;
this.db = db; this.db = db;
this.user = user; this.userProvider = userProvider;
this.changeKindCache = changeKindCache; this.changeKindCache = changeKindCache;
this.psUtil = psUtil; this.psUtil = psUtil;
} }
/** /**
* Retrieve edit for a change and the user from the request scope. * Retrieve edit for a given change.
* *
* <p>At most one change edit can exist per user and change. * <p>At most one change edit can exist per user and change.
* *
* @param change * @param notes change notes of change to retrieve change edits for.
* @return edit for this change for this user, if present. * @return edit for this change for this user, if present.
* @throws AuthException * @throws AuthException if this is not a logged-in user.
* @throws IOException * @throws IOException if an error occurs.
* @throws OrmException
*/ */
public Optional<ChangeEdit> byChange(Change change) public Optional<ChangeEdit> byChange(ChangeNotes notes) throws AuthException, IOException {
throws AuthException, IOException, OrmException { return byChange(notes, userProvider.get());
try {
return byChange(changeControlFactory.controlFor(db.get(), change, user.get()));
} catch (NoSuchChangeException e) {
throw new IOException(e);
}
} }
/** /**
@@ -122,17 +113,19 @@ public class ChangeEditUtil {
* *
* <p>At most one change edit can exist per user and change. * <p>At most one change edit can exist per user and change.
* *
* @param ctl control with user to retrieve change edits for. * @param notes change notes of change to retrieve change edits for.
* @param user user to retrieve edits as.
* @return edit for this change for this user, if present. * @return edit for this change for this user, if present.
* @throws AuthException if this is not a logged-in user. * @throws AuthException if this is not a logged-in user.
* @throws IOException if an error occurs. * @throws IOException if an error occurs.
*/ */
public Optional<ChangeEdit> byChange(ChangeControl ctl) throws AuthException, IOException { public Optional<ChangeEdit> byChange(ChangeNotes notes, CurrentUser user)
if (!ctl.getUser().isIdentifiedUser()) { throws AuthException, IOException {
if (!user.isIdentifiedUser()) {
throw new AuthException("Authentication required"); throw new AuthException("Authentication required");
} }
IdentifiedUser u = ctl.getUser().asIdentifiedUser(); IdentifiedUser u = user.asIdentifiedUser();
Change change = ctl.getChange(); Change change = notes.getChange();
try (Repository repo = gitManager.openRepository(change.getProject())) { try (Repository repo = gitManager.openRepository(change.getProject())) {
int n = change.currentPatchSetId().get(); int n = change.currentPatchSetId().get();
String[] refNames = new String[n]; String[] refNames = new String[n];
@@ -146,7 +139,7 @@ public class ChangeEditUtil {
} }
try (RevWalk rw = new RevWalk(repo)) { try (RevWalk rw = new RevWalk(repo)) {
RevCommit commit = rw.parseCommit(ref.getObjectId()); RevCommit commit = rw.parseCommit(ref.getObjectId());
PatchSet basePs = getBasePatchSet(ctl, ref); PatchSet basePs = getBasePatchSet(notes, ref);
return Optional.of(new ChangeEdit(change, ref.getName(), commit, basePs)); return Optional.of(new ChangeEdit(change, ref.getName(), commit, basePs));
} }
} }
@@ -244,13 +237,13 @@ public class ChangeEditUtil {
indexer.index(db.get(), change); indexer.index(db.get(), change);
} }
private PatchSet getBasePatchSet(ChangeControl ctl, Ref ref) throws IOException { private PatchSet getBasePatchSet(ChangeNotes notes, Ref ref) throws IOException {
try { try {
int pos = ref.getName().lastIndexOf("/"); int pos = ref.getName().lastIndexOf("/");
checkArgument(pos > 0, "invalid edit ref: %s", ref.getName()); checkArgument(pos > 0, "invalid edit ref: %s", ref.getName());
String psId = ref.getName().substring(pos + 1); String psId = ref.getName().substring(pos + 1);
return psUtil.get( return psUtil.get(
db.get(), ctl.getNotes(), new PatchSet.Id(ctl.getId(), Integer.parseInt(psId))); db.get(), notes, new PatchSet.Id(notes.getChange().getId(), Integer.parseInt(psId)));
} catch (OrmException | NumberFormatException e) { } catch (OrmException | NumberFormatException e) {
throw new IOException(e); throw new IOException(e);
} }

View File

@@ -2440,7 +2440,7 @@ class ReceiveCommits {
Optional<ChangeEdit> edit = null; Optional<ChangeEdit> edit = null;
try { try {
edit = editUtil.byChange(projectControl.controlFor(notes)); edit = editUtil.byChange(notes, user);
} catch (AuthException | IOException e) { } catch (AuthException | IOException e) {
logError("Cannot retrieve edit", e); logError("Cannot retrieve edit", e);
return false; return false;

View File

@@ -270,7 +270,7 @@ public class PatchScriptFactory implements Callable<PatchScript> {
} }
private ObjectId getEditRev() throws AuthException, IOException, OrmException { private ObjectId getEditRev() throws AuthException, IOException, OrmException {
edit = editReader.byChange(change); edit = editReader.byChange(control.getNotes());
if (edit.isPresent()) { if (edit.isPresent()) {
return edit.get().getEditCommit(); return edit.get().getEditCommit();
} }