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:
@@ -133,7 +133,7 @@ public class CatServlet extends HttpServlet {
|
||||
.check(ChangePermission.READ);
|
||||
if (patchKey.getParentKey().get() == 0) {
|
||||
// change edit
|
||||
Optional<ChangeEdit> edit = changeEditUtil.byChange(notes.getChange());
|
||||
Optional<ChangeEdit> edit = changeEditUtil.byChange(notes);
|
||||
if (edit.isPresent()) {
|
||||
revision = ObjectId.toString(edit.get().getEditCommit());
|
||||
} else {
|
||||
|
||||
@@ -172,7 +172,7 @@ public class ChangeEditApiImpl implements ChangeEditApi {
|
||||
@Override
|
||||
public void modifyFile(String filePath, RawInput newContent) throws RestApiException {
|
||||
try {
|
||||
changeEditsPut.apply(changeResource.getControl(), filePath, newContent);
|
||||
changeEditsPut.apply(changeResource, filePath, newContent);
|
||||
} catch (Exception e) {
|
||||
throw asRestApiException("Cannot modify file of change edit", e);
|
||||
}
|
||||
@@ -181,7 +181,7 @@ public class ChangeEditApiImpl implements ChangeEditApi {
|
||||
@Override
|
||||
public void deleteFile(String filePath) throws RestApiException {
|
||||
try {
|
||||
changeEditDeleteContent.apply(changeResource.getControl(), filePath);
|
||||
changeEditDeleteContent.apply(changeResource, filePath);
|
||||
} catch (Exception e) {
|
||||
throw asRestApiException("Cannot delete file of change edit", e);
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.CurrentUser;
|
||||
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.PermissionBackendException;
|
||||
import com.google.gerrit.server.project.ChangeControl;
|
||||
@@ -76,49 +77,58 @@ public class Abandon extends RetryingRestModifyView<ChangeResource, AbandonInput
|
||||
IOException, ConfigInvalidException {
|
||||
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 =
|
||||
abandon(
|
||||
updateFactory,
|
||||
req.getControl(),
|
||||
req.getNotes(),
|
||||
req.getUser(),
|
||||
input.message,
|
||||
notify,
|
||||
notifyUtil.resolveAccounts(input.notifyDetails));
|
||||
return json.noOptions().format(change);
|
||||
}
|
||||
|
||||
private NotifyHandling defaultNotify(ChangeControl control) {
|
||||
return control.getChange().hasReviewStarted() ? NotifyHandling.ALL : NotifyHandling.OWNER;
|
||||
private NotifyHandling defaultNotify(Change change) {
|
||||
return change.hasReviewStarted() ? NotifyHandling.ALL : NotifyHandling.OWNER;
|
||||
}
|
||||
|
||||
public Change abandon(BatchUpdate.Factory updateFactory, ChangeControl control)
|
||||
throws RestApiException, UpdateException {
|
||||
return abandon(updateFactory, control, "", defaultNotify(control), ImmutableListMultimap.of());
|
||||
}
|
||||
|
||||
public Change abandon(BatchUpdate.Factory updateFactory, ChangeControl control, String msgTxt)
|
||||
public Change abandon(BatchUpdate.Factory updateFactory, ChangeNotes notes, CurrentUser user)
|
||||
throws RestApiException, UpdateException {
|
||||
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(
|
||||
BatchUpdate.Factory updateFactory,
|
||||
ChangeControl control,
|
||||
ChangeNotes notes,
|
||||
CurrentUser user,
|
||||
String msgTxt,
|
||||
NotifyHandling notifyHandling,
|
||||
ListMultimap<RecipientType, Account.Id> accountsToNotify)
|
||||
throws RestApiException, UpdateException {
|
||||
CurrentUser user = control.getUser();
|
||||
Account account = user.isIdentifiedUser() ? user.asIdentifiedUser().getAccount() : null;
|
||||
AbandonOp op = abandonOpFactory.create(account, msgTxt, notifyHandling, accountsToNotify);
|
||||
try (BatchUpdate u =
|
||||
updateFactory.create(
|
||||
dbProvider.get(),
|
||||
control.getProject().getNameKey(),
|
||||
control.getUser(),
|
||||
TimeUtil.nowTs())) {
|
||||
u.addOp(control.getId(), op).execute();
|
||||
updateFactory.create(dbProvider.get(), notes.getProjectName(), user, TimeUtil.nowTs())) {
|
||||
u.addOp(notes.getChangeId(), op).execute();
|
||||
}
|
||||
return op.getChange();
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ public class ApplyFix implements RestModifyView<FixResource, Void> {
|
||||
repository, projectState, patchSetCommitId, fixResource.getFixReplacements());
|
||||
ChangeEdit changeEdit =
|
||||
changeEditModifier.combineWithModifiedPatchSetTree(
|
||||
repository, revisionResource.getControl(), patchSet, treeModifications);
|
||||
repository, revisionResource.getNotes(), patchSet, treeModifications);
|
||||
return Response.ok(changeEditJson.toEditInfo(changeEdit, false));
|
||||
} catch (InvalidChangeOperationException e) {
|
||||
throw new ResourceConflictException(e.getMessage());
|
||||
|
||||
@@ -17,7 +17,6 @@ package com.google.gerrit.server.change;
|
||||
import com.google.gerrit.extensions.restapi.RestResource;
|
||||
import com.google.gerrit.extensions.restapi.RestView;
|
||||
import com.google.gerrit.server.edit.ChangeEdit;
|
||||
import com.google.gerrit.server.project.ChangeControl;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
@@ -54,10 +53,6 @@ public class ChangeEditResource implements RestResource {
|
||||
return change;
|
||||
}
|
||||
|
||||
public ChangeControl getControl() {
|
||||
return getChangeResource().getControl();
|
||||
}
|
||||
|
||||
public ChangeEdit getChangeEdit() {
|
||||
return edit;
|
||||
}
|
||||
|
||||
@@ -47,7 +47,6 @@ import com.google.gerrit.server.edit.UnchangedCommitMessageException;
|
||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
import com.google.gerrit.server.patch.PatchListNotAvailableException;
|
||||
import com.google.gerrit.server.permissions.PermissionBackendException;
|
||||
import com.google.gerrit.server.project.ChangeControl;
|
||||
import com.google.gerrit.server.project.InvalidChangeOperationException;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
@@ -105,7 +104,7 @@ public class ChangeEdits
|
||||
@Override
|
||||
public ChangeEditResource parse(ChangeResource rsrc, IdString id)
|
||||
throws ResourceNotFoundException, AuthException, IOException, OrmException {
|
||||
Optional<ChangeEdit> edit = editUtil.byChange(rsrc.getChange());
|
||||
Optional<ChangeEdit> edit = editUtil.byChange(rsrc.getNotes(), rsrc.getUser());
|
||||
if (!edit.isPresent()) {
|
||||
throw new ResourceNotFoundException(id);
|
||||
}
|
||||
@@ -157,7 +156,7 @@ public class ChangeEdits
|
||||
public Response<?> apply(ChangeResource resource, Put.Input input)
|
||||
throws AuthException, ResourceConflictException, IOException, OrmException,
|
||||
PermissionBackendException {
|
||||
putEdit.apply(resource.getControl(), path, input.content);
|
||||
putEdit.apply(resource, path, input.content);
|
||||
return Response.none();
|
||||
}
|
||||
}
|
||||
@@ -182,7 +181,7 @@ public class ChangeEdits
|
||||
public Response<?> apply(ChangeResource rsrc, DeleteFile.Input in)
|
||||
throws IOException, AuthException, ResourceConflictException, OrmException,
|
||||
PermissionBackendException {
|
||||
return deleteContent.apply(rsrc.getControl(), path);
|
||||
return deleteContent.apply(rsrc, path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,7 +217,7 @@ public class ChangeEdits
|
||||
@Override
|
||||
public Response<EditInfo> apply(ChangeResource rsrc)
|
||||
throws AuthException, IOException, ResourceNotFoundException, OrmException {
|
||||
Optional<ChangeEdit> edit = editUtil.byChange(rsrc.getChange());
|
||||
Optional<ChangeEdit> edit = editUtil.byChange(rsrc.getNotes(), rsrc.getUser());
|
||||
if (!edit.isPresent()) {
|
||||
return Response.none();
|
||||
}
|
||||
@@ -275,13 +274,12 @@ public class ChangeEdits
|
||||
PermissionBackendException {
|
||||
Project.NameKey project = resource.getProject();
|
||||
try (Repository repository = repositoryManager.openRepository(project)) {
|
||||
ChangeControl changeControl = resource.getControl();
|
||||
if (isRestoreFile(input)) {
|
||||
editModifier.restoreFile(repository, changeControl, input.restorePath);
|
||||
editModifier.restoreFile(repository, resource.getNotes(), input.restorePath);
|
||||
} else if (isRenameFile(input)) {
|
||||
editModifier.renameFile(repository, changeControl, input.oldPath, input.newPath);
|
||||
editModifier.renameFile(repository, resource.getNotes(), input.oldPath, input.newPath);
|
||||
} else {
|
||||
editModifier.createEdit(repository, changeControl);
|
||||
editModifier.createEdit(repository, resource.getNotes());
|
||||
}
|
||||
} catch (InvalidChangeOperationException e) {
|
||||
throw new ResourceConflictException(e.getMessage());
|
||||
@@ -320,19 +318,18 @@ public class ChangeEdits
|
||||
public Response<?> apply(ChangeEditResource rsrc, Input input)
|
||||
throws AuthException, ResourceConflictException, IOException, OrmException,
|
||||
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,
|
||||
PermissionBackendException {
|
||||
if (Strings.isNullOrEmpty(path) || path.charAt(0) == '/') {
|
||||
throw new ResourceConflictException("Invalid path: " + path);
|
||||
}
|
||||
|
||||
Project.NameKey project = changeControl.getChange().getProject();
|
||||
try (Repository repository = repositoryManager.openRepository(project)) {
|
||||
editModifier.modifyFile(repository, changeControl, path, newContent);
|
||||
try (Repository repository = repositoryManager.openRepository(rsrc.getProject())) {
|
||||
editModifier.modifyFile(repository, rsrc.getNotes(), path, newContent);
|
||||
} catch (InvalidChangeOperationException e) {
|
||||
throw new ResourceConflictException(e.getMessage());
|
||||
}
|
||||
@@ -364,15 +361,14 @@ public class ChangeEdits
|
||||
public Response<?> apply(ChangeEditResource rsrc, DeleteContent.Input input)
|
||||
throws AuthException, ResourceConflictException, OrmException, IOException,
|
||||
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,
|
||||
PermissionBackendException {
|
||||
Project.NameKey project = changeControl.getChange().getProject();
|
||||
try (Repository repository = repositoryManager.openRepository(project)) {
|
||||
editModifier.deleteFile(repository, changeControl, filePath);
|
||||
try (Repository repository = repositoryManager.openRepository(rsrc.getProject())) {
|
||||
editModifier.deleteFile(repository, rsrc.getNotes(), filePath);
|
||||
} catch (InvalidChangeOperationException e) {
|
||||
throw new ResourceConflictException(e.getMessage());
|
||||
}
|
||||
@@ -401,7 +397,7 @@ public class ChangeEdits
|
||||
ChangeEdit edit = rsrc.getChangeEdit();
|
||||
return Response.ok(
|
||||
fileContentUtil.getContent(
|
||||
rsrc.getControl().getProjectControl().getProjectState(),
|
||||
rsrc.getChangeResource().getControl().getProjectControl().getProjectState(),
|
||||
base
|
||||
? ObjectId.fromString(edit.getBasePatchSet().getRevision().get())
|
||||
: edit.getEditCommit(),
|
||||
@@ -471,8 +467,7 @@ public class ChangeEdits
|
||||
|
||||
Project.NameKey project = rsrc.getProject();
|
||||
try (Repository repository = repositoryManager.openRepository(project)) {
|
||||
ChangeControl changeControl = rsrc.getControl();
|
||||
editModifier.modifyMessage(repository, changeControl, input.message);
|
||||
editModifier.modifyMessage(repository, rsrc.getNotes(), input.message);
|
||||
} catch (UnchangedCommitMessageException e) {
|
||||
throw new ResourceConflictException(e.getMessage());
|
||||
}
|
||||
@@ -501,7 +496,7 @@ public class ChangeEdits
|
||||
@Override
|
||||
public BinaryResult apply(ChangeResource rsrc)
|
||||
throws AuthException, IOException, ResourceNotFoundException, OrmException {
|
||||
Optional<ChangeEdit> edit = editUtil.byChange(rsrc.getChange());
|
||||
Optional<ChangeEdit> edit = editUtil.byChange(rsrc.getNotes(), rsrc.getUser());
|
||||
String msg;
|
||||
if (edit.isPresent()) {
|
||||
if (base) {
|
||||
|
||||
@@ -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.RestReadView;
|
||||
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.server.PatchSetUtil;
|
||||
import com.google.gerrit.server.project.ChangeControl;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
@@ -44,9 +42,7 @@ public class ChangeIncludedIn implements RestReadView<ChangeResource> {
|
||||
@Override
|
||||
public IncludedInInfo apply(ChangeResource rsrc)
|
||||
throws RestApiException, OrmException, IOException {
|
||||
ChangeControl ctl = rsrc.getControl();
|
||||
PatchSet ps = psUtil.current(db.get(), rsrc.getNotes());
|
||||
Project.NameKey project = ctl.getProject().getNameKey();
|
||||
return includedIn.apply(project, ps.getRevision().get());
|
||||
return includedIn.apply(rsrc.getProject(), ps.getRevision().get());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -285,7 +285,7 @@ public class ChangeJson {
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
@@ -27,7 +27,6 @@ import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||
import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
import com.google.gerrit.server.CurrentUser;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.gerrit.server.StarredChangesUtil;
|
||||
import com.google.gerrit.server.notedb.ChangeNotes;
|
||||
import com.google.gerrit.server.permissions.PermissionBackend;
|
||||
@@ -77,8 +76,8 @@ public class ChangeResource implements RestResource, HasETag {
|
||||
return control;
|
||||
}
|
||||
|
||||
public IdentifiedUser getUser() {
|
||||
return getControl().getUser().asIdentifiedUser();
|
||||
public CurrentUser getUser() {
|
||||
return getControl().getUser();
|
||||
}
|
||||
|
||||
public Change.Id getId() {
|
||||
|
||||
@@ -42,7 +42,6 @@ import com.google.gerrit.server.git.MergeIdenticalTreeException;
|
||||
import com.google.gerrit.server.git.MergeUtil;
|
||||
import com.google.gerrit.server.permissions.ChangePermission;
|
||||
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.InvalidChangeOperationException;
|
||||
import com.google.gerrit.server.project.ProjectControl;
|
||||
@@ -117,11 +116,10 @@ public class CreateMergePatchSet
|
||||
throw new BadRequestException("merge.source must be non-empty");
|
||||
}
|
||||
|
||||
ChangeControl ctl = rsrc.getControl();
|
||||
PatchSet ps = psUtil.current(db.get(), ctl.getNotes());
|
||||
ProjectControl projectControl = ctl.getProjectControl();
|
||||
PatchSet ps = psUtil.current(db.get(), rsrc.getNotes());
|
||||
ProjectControl projectControl = rsrc.getControl().getProjectControl();
|
||||
ProjectState state = projectControl.getProjectState();
|
||||
Change change = ctl.getChange();
|
||||
Change change = rsrc.getChange();
|
||||
Project.NameKey project = change.getProject();
|
||||
Branch.NameKey dest = change.getDest();
|
||||
try (Repository git = gitManager.openRepository(project);
|
||||
@@ -153,11 +151,12 @@ public class CreateMergePatchSet
|
||||
ObjectId.fromString(change.getKey().get().substring(1)));
|
||||
|
||||
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)) {
|
||||
bu.setRepository(git, rw, oi);
|
||||
bu.addOp(
|
||||
ctl.getId(),
|
||||
rsrc.getId(),
|
||||
psInserter
|
||||
.setMessage("Uploaded patch set " + nextPsId.get() + ".")
|
||||
.setDraft(ps.isDraft())
|
||||
|
||||
@@ -41,7 +41,7 @@ public class DeleteChangeEdit implements RestModifyView<ChangeResource, Input> {
|
||||
@Override
|
||||
public Response<?> apply(ChangeResource rsrc, Input input)
|
||||
throws AuthException, ResourceNotFoundException, IOException, OrmException {
|
||||
Optional<ChangeEdit> edit = editUtil.byChange(rsrc.getChange());
|
||||
Optional<ChangeEdit> edit = editUtil.byChange(rsrc.getNotes(), rsrc.getUser());
|
||||
if (edit.isPresent()) {
|
||||
editUtil.delete(edit.get());
|
||||
} else {
|
||||
|
||||
@@ -27,7 +27,6 @@ import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.ChangeMessagesUtil;
|
||||
import com.google.gerrit.server.permissions.GlobalPermission;
|
||||
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.RetryHelper;
|
||||
import com.google.gerrit.server.update.RetryingRestModifyView;
|
||||
@@ -67,15 +66,11 @@ public class DeletePrivate
|
||||
throw new ResourceConflictException("change is not private");
|
||||
}
|
||||
|
||||
ChangeControl control = rsrc.getControl();
|
||||
SetPrivateOp op = new SetPrivateOp(cmUtil, false, input);
|
||||
try (BatchUpdate u =
|
||||
updateFactory.create(
|
||||
dbProvider.get(),
|
||||
control.getProject().getNameKey(),
|
||||
control.getUser(),
|
||||
TimeUtil.nowTs())) {
|
||||
u.addOp(control.getId(), op).execute();
|
||||
dbProvider.get(), rsrc.getProject(), rsrc.getUser(), TimeUtil.nowTs())) {
|
||||
u.addOp(rsrc.getId(), op).execute();
|
||||
}
|
||||
|
||||
return Response.none();
|
||||
|
||||
@@ -19,7 +19,6 @@ import com.google.gerrit.extensions.restapi.BadRequestException;
|
||||
import com.google.gerrit.extensions.restapi.Response;
|
||||
import com.google.gerrit.extensions.restapi.RestReadView;
|
||||
import com.google.gerrit.server.notedb.ChangeNotes;
|
||||
import com.google.gerrit.server.project.ChangeControl;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.inject.Singleton;
|
||||
import java.io.IOException;
|
||||
@@ -31,8 +30,7 @@ public class GetHashtags implements RestReadView<ChangeResource> {
|
||||
@Override
|
||||
public Response<Set<String>> apply(ChangeResource req)
|
||||
throws AuthException, OrmException, IOException, BadRequestException {
|
||||
ChangeControl control = req.getControl();
|
||||
ChangeNotes notes = control.getNotes().load();
|
||||
ChangeNotes notes = req.getNotes().load();
|
||||
Set<String> hashtags = notes.getHashtags();
|
||||
if (hashtags == null) {
|
||||
hashtags = Collections.emptySet();
|
||||
|
||||
@@ -40,7 +40,7 @@ public class GetPastAssignees implements RestReadView<ChangeResource> {
|
||||
@Override
|
||||
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) {
|
||||
return Response.ok(Collections.emptyList());
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ public class ListChangeComments implements RestReadView<ChangeResource> {
|
||||
@Override
|
||||
public Map<String, List<CommentInfo>> apply(ChangeResource rsrc)
|
||||
throws AuthException, OrmException {
|
||||
ChangeData cd = changeDataFactory.create(db.get(), rsrc.getControl());
|
||||
ChangeData cd = changeDataFactory.create(db.get(), rsrc.getNotes());
|
||||
return commentJson
|
||||
.get()
|
||||
.setFillAccounts(true)
|
||||
|
||||
@@ -50,13 +50,12 @@ public class ListChangeDrafts implements RestReadView<ChangeResource> {
|
||||
@Override
|
||||
public Map<String, List<CommentInfo>> apply(ChangeResource rsrc)
|
||||
throws AuthException, OrmException {
|
||||
if (!rsrc.getControl().getUser().isIdentifiedUser()) {
|
||||
if (!rsrc.getUser().isIdentifiedUser()) {
|
||||
throw new AuthException("Authentication required");
|
||||
}
|
||||
ChangeData cd = changeDataFactory.create(db.get(), rsrc.getControl());
|
||||
ChangeData cd = changeDataFactory.create(db.get(), rsrc.getNotes());
|
||||
List<Comment> drafts =
|
||||
commentsUtil.draftByChangeAuthor(
|
||||
db.get(), cd.notes(), rsrc.getControl().getUser().getAccountId());
|
||||
commentsUtil.draftByChangeAuthor(db.get(), cd.notes(), rsrc.getUser().getAccountId());
|
||||
return commentJson
|
||||
.get()
|
||||
.setFillAccounts(false)
|
||||
|
||||
@@ -47,7 +47,7 @@ public class ListChangeRobotComments implements RestReadView<ChangeResource> {
|
||||
@Override
|
||||
public Map<String, List<RobotCommentInfo>> apply(ChangeResource rsrc)
|
||||
throws AuthException, OrmException {
|
||||
ChangeData cd = changeDataFactory.create(db.get(), rsrc.getControl());
|
||||
ChangeData cd = changeDataFactory.create(db.get(), rsrc.getNotes());
|
||||
return commentJson
|
||||
.get()
|
||||
.setFillAccounts(true)
|
||||
|
||||
@@ -98,7 +98,7 @@ public class Move extends RetryingRestModifyView<ChangeResource, MoveInput, Chan
|
||||
throws RestApiException, OrmException, UpdateException, PermissionBackendException {
|
||||
Change change = rsrc.getChange();
|
||||
Project.NameKey project = rsrc.getProject();
|
||||
IdentifiedUser caller = rsrc.getUser();
|
||||
IdentifiedUser caller = rsrc.getUser().asIdentifiedUser();
|
||||
input.destinationBranch = RefNames.fullName(input.destinationBranch);
|
||||
|
||||
if (change.getStatus().isClosed()) {
|
||||
|
||||
@@ -55,7 +55,7 @@ public class PostHashtags
|
||||
|
||||
try (BatchUpdate bu =
|
||||
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);
|
||||
bu.addOp(req.getId(), op);
|
||||
bu.execute();
|
||||
|
||||
@@ -28,7 +28,6 @@ import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.ChangeMessagesUtil;
|
||||
import com.google.gerrit.server.permissions.GlobalPermission;
|
||||
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.RetryHelper;
|
||||
import com.google.gerrit.server.update.RetryingRestModifyView;
|
||||
@@ -69,15 +68,11 @@ public class PostPrivate
|
||||
return Response.ok("");
|
||||
}
|
||||
|
||||
ChangeControl control = rsrc.getControl();
|
||||
SetPrivateOp op = new SetPrivateOp(cmUtil, true, input);
|
||||
try (BatchUpdate u =
|
||||
updateFactory.create(
|
||||
dbProvider.get(),
|
||||
control.getProject().getNameKey(),
|
||||
control.getUser(),
|
||||
TimeUtil.nowTs())) {
|
||||
u.addOp(control.getId(), op).execute();
|
||||
dbProvider.get(), rsrc.getProject(), rsrc.getUser(), TimeUtil.nowTs())) {
|
||||
u.addOp(rsrc.getId(), op).execute();
|
||||
}
|
||||
|
||||
return Response.created("");
|
||||
|
||||
@@ -60,7 +60,6 @@ import com.google.gerrit.server.permissions.ChangePermission;
|
||||
import com.google.gerrit.server.permissions.PermissionBackend;
|
||||
import com.google.gerrit.server.permissions.PermissionBackendException;
|
||||
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.ProjectCache;
|
||||
import com.google.gerrit.server.query.change.ChangeData;
|
||||
@@ -286,13 +285,12 @@ public class PostReviewers
|
||||
}
|
||||
|
||||
Set<Account.Id> reviewers = new HashSet<>();
|
||||
ChangeControl control = rsrc.getControl();
|
||||
Set<Account> members;
|
||||
try {
|
||||
members =
|
||||
groupMembersFactory
|
||||
.create(control.getUser())
|
||||
.listAccounts(group.getGroupUUID(), control.getProject().getNameKey());
|
||||
.create(rsrc.getUser())
|
||||
.listAccounts(group.getGroupUUID(), rsrc.getProject());
|
||||
} catch (NoSuchGroupException e) {
|
||||
return fail(
|
||||
reviewer,
|
||||
@@ -424,7 +422,7 @@ public class PostReviewers
|
||||
this.reviewersByEmail = reviewersByEmail == null ? ImmutableList.of() : reviewersByEmail;
|
||||
this.state = state;
|
||||
notes = rsrc.getNotes();
|
||||
caller = rsrc.getUser();
|
||||
caller = rsrc.getUser().asIdentifiedUser();
|
||||
op =
|
||||
postReviewersOpFactory.create(
|
||||
rsrc, this.reviewers, this.reviewersByEmail, state, notify, accountsToNotify);
|
||||
|
||||
@@ -89,7 +89,7 @@ public class PublishChangeEdit
|
||||
throws IOException, OrmException, RestApiException, UpdateException,
|
||||
ConfigInvalidException {
|
||||
CreateChange.checkValidCLA(rsrc.getControl().getProjectControl());
|
||||
Optional<ChangeEdit> edit = editUtil.byChange(rsrc.getChange());
|
||||
Optional<ChangeEdit> edit = editUtil.byChange(rsrc.getNotes(), rsrc.getUser());
|
||||
if (!edit.isPresent()) {
|
||||
throw new ResourceConflictException(
|
||||
String.format("no edit exists for change %s", rsrc.getChange().getChangeId()));
|
||||
|
||||
@@ -155,7 +155,7 @@ public class PublishDraftPatchSet
|
||||
throws RestApiException, UpdateException {
|
||||
return publish.apply(
|
||||
updateFactory,
|
||||
rsrc.getControl().getUser(),
|
||||
rsrc.getUser(),
|
||||
rsrc.getChange(),
|
||||
rsrc.getChange().currentPatchSetId(),
|
||||
null);
|
||||
|
||||
@@ -94,10 +94,7 @@ public class PutAssignee extends RetryingRestModifyView<ChangeResource, Assignee
|
||||
|
||||
try (BatchUpdate bu =
|
||||
updateFactory.create(
|
||||
db.get(),
|
||||
rsrc.getChange().getProject(),
|
||||
rsrc.getControl().getUser(),
|
||||
TimeUtil.nowTs())) {
|
||||
db.get(), rsrc.getChange().getProject(), rsrc.getUser(), TimeUtil.nowTs())) {
|
||||
SetAssigneeOp op = assigneeFactory.create(assignee);
|
||||
bu.addOp(rsrc.getId(), op);
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ public class PutMessage
|
||||
}
|
||||
String sanitizedCommitMessage = CommitMessageUtil.checkAndSanitizeCommitMessage(input.message);
|
||||
|
||||
ensureCanEditCommitMessage(resource.getControl().getNotes());
|
||||
ensureCanEditCommitMessage(resource.getNotes());
|
||||
ensureChangeIdIsCorrect(
|
||||
resource.getControl().getProjectControl().getProjectState().isRequireChangeID(),
|
||||
resource.getChange().getKey().get(),
|
||||
|
||||
@@ -87,7 +87,7 @@ public class RebaseChangeEdit
|
||||
PermissionBackendException {
|
||||
Project.NameKey project = rsrc.getProject();
|
||||
try (Repository repository = repositoryManager.openRepository(project)) {
|
||||
editModifier.rebaseEdit(repository, rsrc.getControl());
|
||||
editModifier.rebaseEdit(repository, rsrc.getNotes());
|
||||
} catch (InvalidChangeOperationException e) {
|
||||
throw new ResourceConflictException(e.getMessage());
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@ import com.google.gerrit.server.mail.send.RestoredSender;
|
||||
import com.google.gerrit.server.notedb.ChangeUpdate;
|
||||
import com.google.gerrit.server.permissions.ChangePermission;
|
||||
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.BatchUpdateOp;
|
||||
import com.google.gerrit.server.update.ChangeContext;
|
||||
@@ -88,11 +87,10 @@ public class Restore extends RetryingRestModifyView<ChangeResource, RestoreInput
|
||||
throws RestApiException, UpdateException, OrmException, PermissionBackendException {
|
||||
req.permissions().database(dbProvider).check(ChangePermission.RESTORE);
|
||||
|
||||
ChangeControl ctl = req.getControl();
|
||||
Op op = new Op(input);
|
||||
try (BatchUpdate u =
|
||||
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();
|
||||
}
|
||||
return json.noOptions().format(op.change);
|
||||
|
||||
@@ -42,10 +42,10 @@ import com.google.gerrit.server.Sequences;
|
||||
import com.google.gerrit.server.extensions.events.ChangeReverted;
|
||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
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.permissions.PermissionBackend;
|
||||
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.update.BatchUpdate;
|
||||
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 PermissionBackend permissionBackend;
|
||||
private final Provider<CurrentUser> user;
|
||||
private final GitRepositoryManager repoManager;
|
||||
private final ChangeInserter.Factory changeInserterFactory;
|
||||
private final ChangeMessagesUtil cmUtil;
|
||||
@@ -99,7 +98,6 @@ public class Revert extends RetryingRestModifyView<ChangeResource, RevertInput,
|
||||
Revert(
|
||||
Provider<ReviewDb> db,
|
||||
PermissionBackend permissionBackend,
|
||||
Provider<CurrentUser> user,
|
||||
GitRepositoryManager repoManager,
|
||||
ChangeInserter.Factory changeInserterFactory,
|
||||
ChangeMessagesUtil cmUtil,
|
||||
@@ -114,7 +112,6 @@ public class Revert extends RetryingRestModifyView<ChangeResource, RevertInput,
|
||||
super(retryHelper);
|
||||
this.db = db;
|
||||
this.permissionBackend = permissionBackend;
|
||||
this.user = user;
|
||||
this.repoManager = repoManager;
|
||||
this.changeInserterFactory = changeInserterFactory;
|
||||
this.cmUtil = cmUtil;
|
||||
@@ -138,24 +135,24 @@ public class Revert extends RetryingRestModifyView<ChangeResource, RevertInput,
|
||||
}
|
||||
|
||||
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 =
|
||||
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);
|
||||
}
|
||||
|
||||
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 {
|
||||
Change.Id changeIdToRevert = ctl.getChange().getId();
|
||||
PatchSet.Id patchSetId = ctl.getChange().currentPatchSetId();
|
||||
PatchSet patch = psUtil.get(db.get(), ctl.getNotes(), patchSetId);
|
||||
Change.Id changeIdToRevert = notes.getChangeId();
|
||||
PatchSet.Id patchSetId = notes.getChange().currentPatchSetId();
|
||||
PatchSet patch = psUtil.get(db.get(), notes, patchSetId);
|
||||
if (patch == null) {
|
||||
throw new ResourceNotFoundException(changeIdToRevert.toString());
|
||||
}
|
||||
|
||||
Project.NameKey project = ctl.getProject().getNameKey();
|
||||
CurrentUser user = ctl.getUser();
|
||||
Project.NameKey project = notes.getProjectName();
|
||||
try (Repository git = repoManager.openRepository(project);
|
||||
ObjectInserter oi = git.newObjectInserter();
|
||||
ObjectReader reader = oi.newReader();
|
||||
@@ -180,7 +177,7 @@ public class Revert extends RetryingRestModifyView<ChangeResource, RevertInput,
|
||||
revertCommitBuilder.setAuthor(authorIdent);
|
||||
revertCommitBuilder.setCommitter(authorIdent);
|
||||
|
||||
Change changeToRevert = ctl.getChange();
|
||||
Change changeToRevert = notes.getChange();
|
||||
if (message == null) {
|
||||
message =
|
||||
MessageFormat.format(
|
||||
@@ -204,11 +201,11 @@ public class Revert extends RetryingRestModifyView<ChangeResource, RevertInput,
|
||||
|
||||
ChangeInserter ins =
|
||||
changeInserterFactory
|
||||
.create(changeId, revertCommit, ctl.getChange().getDest().get())
|
||||
.create(changeId, revertCommit, notes.getChange().getDest().get())
|
||||
.setTopic(changeToRevert.getTopic());
|
||||
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<>();
|
||||
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)) {
|
||||
bu.setRepository(git, revWalk, oi);
|
||||
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.execute();
|
||||
}
|
||||
@@ -243,7 +240,10 @@ public class Revert extends RetryingRestModifyView<ChangeResource, RevertInput,
|
||||
.setVisible(
|
||||
and(
|
||||
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 {
|
||||
|
||||
@@ -140,8 +140,8 @@ public class Revisions implements ChildCollection<ChangeResource, RevisionResour
|
||||
}
|
||||
|
||||
private List<RevisionResource> loadEdit(ChangeResource change, RevId revid)
|
||||
throws AuthException, IOException, OrmException {
|
||||
Optional<ChangeEdit> edit = editUtil.byChange(change.getChange());
|
||||
throws AuthException, IOException {
|
||||
Optional<ChangeEdit> edit = editUtil.byChange(change.getNotes(), change.getUser());
|
||||
if (edit.isPresent()) {
|
||||
PatchSet ps = new PatchSet(new PatchSet.Id(change.getId(), 0));
|
||||
RevId editRevId = new RevId(ObjectId.toString(edit.get().getEditCommit()));
|
||||
|
||||
@@ -125,9 +125,7 @@ public class SubmittedTogether implements RestReadView<ChangeResource> {
|
||||
|
||||
if (c.getStatus().isOpen()) {
|
||||
ChangeSet cs =
|
||||
mergeSuperSet
|
||||
.get()
|
||||
.completeChangeSet(dbProvider.get(), c, resource.getControl().getUser());
|
||||
mergeSuperSet.get().completeChangeSet(dbProvider.get(), c, resource.getUser());
|
||||
cds = cs.changes().asList();
|
||||
hidden = cs.nonVisibleChanges().size();
|
||||
} else if (c.getStatus().asChangeStatus() == ChangeStatus.MERGED) {
|
||||
|
||||
@@ -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.TreeModification;
|
||||
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.PermissionBackend;
|
||||
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.util.CommitMessageUtil;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
@@ -106,34 +106,32 @@ public class ChangeEditModifier {
|
||||
* Creates a new change edit.
|
||||
*
|
||||
* @param repository the affected Git repository
|
||||
* @param changeControl the {@code ChangeControl} of the change for which the change edit should
|
||||
* be created
|
||||
* @param notes the {@link ChangeNotes} of the change for which the change edit should be created
|
||||
* @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 PermissionBackendException
|
||||
*/
|
||||
public void createEdit(Repository repository, ChangeControl changeControl)
|
||||
public void createEdit(Repository repository, ChangeNotes notes)
|
||||
throws AuthException, IOException, InvalidChangeOperationException, OrmException,
|
||||
PermissionBackendException {
|
||||
assertCanEdit(changeControl);
|
||||
assertCanEdit(notes);
|
||||
|
||||
Optional<ChangeEdit> changeEdit = lookupChangeEdit(changeControl);
|
||||
Optional<ChangeEdit> changeEdit = lookupChangeEdit(notes);
|
||||
if (changeEdit.isPresent()) {
|
||||
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);
|
||||
createEdit(repository, changeControl, currentPatchSet, patchSetCommitId, TimeUtil.nowTs());
|
||||
createEdit(repository, notes, currentPatchSet, patchSetCommitId, TimeUtil.nowTs());
|
||||
}
|
||||
|
||||
/**
|
||||
* Rebase change edit on latest patch set
|
||||
*
|
||||
* @param repository the affected Git repository
|
||||
* @param changeControl the {@code ChangeControl} of the change whose change edit should be
|
||||
* rebased
|
||||
* @param notes the {@link ChangeNotes} of the change whose change edit should be rebased
|
||||
* @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
|
||||
* 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 PermissionBackendException
|
||||
*/
|
||||
public void rebaseEdit(Repository repository, ChangeControl changeControl)
|
||||
public void rebaseEdit(Repository repository, ChangeNotes notes)
|
||||
throws AuthException, InvalidChangeOperationException, IOException, OrmException,
|
||||
MergeConflictException, PermissionBackendException {
|
||||
assertCanEdit(changeControl);
|
||||
assertCanEdit(notes);
|
||||
|
||||
Optional<ChangeEdit> optionalChangeEdit = lookupChangeEdit(changeControl);
|
||||
Optional<ChangeEdit> optionalChangeEdit = lookupChangeEdit(notes);
|
||||
if (!optionalChangeEdit.isPresent()) {
|
||||
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();
|
||||
|
||||
PatchSet currentPatchSet = lookupCurrentPatchSet(changeControl);
|
||||
PatchSet currentPatchSet = lookupCurrentPatchSet(notes);
|
||||
if (isBasedOn(changeEdit, currentPatchSet)) {
|
||||
throw new InvalidChangeOperationException(
|
||||
String.format(
|
||||
"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);
|
||||
@@ -198,23 +196,22 @@ public class ChangeEditModifier {
|
||||
* be created based on the current patch set.
|
||||
*
|
||||
* @param repository the affected Git repository
|
||||
* @param changeControl the {@code ChangeControl} of the change whose change edit's message should
|
||||
* be modified
|
||||
* @param notes the {@link ChangeNotes} of the change whose change edit's message should be
|
||||
* modified
|
||||
* @param newCommitMessage the new commit message
|
||||
* @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 PermissionBackendException
|
||||
* @throws BadRequestException if the commit message is malformed
|
||||
*/
|
||||
public void modifyMessage(
|
||||
Repository repository, ChangeControl changeControl, String newCommitMessage)
|
||||
public void modifyMessage(Repository repository, ChangeNotes notes, String newCommitMessage)
|
||||
throws AuthException, IOException, UnchangedCommitMessageException, OrmException,
|
||||
PermissionBackendException, BadRequestException {
|
||||
assertCanEdit(changeControl);
|
||||
assertCanEdit(notes);
|
||||
newCommitMessage = CommitMessageUtil.checkAndSanitizeCommitMessage(newCommitMessage);
|
||||
|
||||
Optional<ChangeEdit> optionalChangeEdit = lookupChangeEdit(changeControl);
|
||||
PatchSet basePatchSet = getBasePatchSet(optionalChangeEdit, changeControl);
|
||||
Optional<ChangeEdit> optionalChangeEdit = lookupChangeEdit(notes);
|
||||
PatchSet basePatchSet = getBasePatchSet(optionalChangeEdit, notes);
|
||||
RevCommit basePatchSetCommit = lookupCommit(repository, basePatchSet);
|
||||
RevCommit baseCommit =
|
||||
optionalChangeEdit.map(ChangeEdit::getEditCommit).orElse(basePatchSetCommit);
|
||||
@@ -232,7 +229,7 @@ public class ChangeEditModifier {
|
||||
if (optionalChangeEdit.isPresent()) {
|
||||
updateEdit(repository, optionalChangeEdit.get(), newEditCommit, nowTimestamp);
|
||||
} 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.
|
||||
*
|
||||
* @param repository the affected Git repository
|
||||
* @param changeControl the {@code ChangeControl} of the change whose change edit should be
|
||||
* modified
|
||||
* @param notes the {@link ChangeNotes} of the change whose change edit should be modified
|
||||
* @param filePath the path of the file whose contents should be modified
|
||||
* @param newContent the new file content
|
||||
* @throws AuthException if the user isn't authenticated or not allowed to use change edits
|
||||
@@ -250,10 +246,10 @@ public class ChangeEditModifier {
|
||||
* @throws PermissionBackendException
|
||||
*/
|
||||
public void modifyFile(
|
||||
Repository repository, ChangeControl changeControl, String filePath, RawInput newContent)
|
||||
Repository repository, ChangeNotes notes, String filePath, RawInput newContent)
|
||||
throws AuthException, InvalidChangeOperationException, IOException, OrmException,
|
||||
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.
|
||||
*
|
||||
* @param repository the affected Git repository
|
||||
* @param changeControl the {@code ChangeControl} of the change whose change edit should be
|
||||
* modified
|
||||
* @param notes the {@link ChangeNotes} of the change whose change edit should be modified
|
||||
* @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 InvalidChangeOperationException if the file does not exist
|
||||
* @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,
|
||||
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.
|
||||
*
|
||||
* @param repository the affected Git repository
|
||||
* @param changeControl the {@code ChangeControl} of the change whose change edit should be
|
||||
* modified
|
||||
* @param notes the {@link ChangeNotes} of the change whose change edit should be modified
|
||||
* @param currentFilePath the current 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
|
||||
@@ -289,13 +283,10 @@ public class ChangeEditModifier {
|
||||
* @throws PermissionBackendException
|
||||
*/
|
||||
public void renameFile(
|
||||
Repository repository,
|
||||
ChangeControl changeControl,
|
||||
String currentFilePath,
|
||||
String newFilePath)
|
||||
Repository repository, ChangeNotes notes, String currentFilePath, String newFilePath)
|
||||
throws AuthException, InvalidChangeOperationException, IOException, OrmException,
|
||||
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.
|
||||
*
|
||||
* @param repository the affected Git repository
|
||||
* @param changeControl the {@code ChangeControl} of the change whose change edit should be
|
||||
* modified
|
||||
* @param notes the {@link ChangeNotes} of the change whose change edit should be modified
|
||||
* @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 InvalidChangeOperationException if the file was already restored
|
||||
* @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,
|
||||
PermissionBackendException {
|
||||
modifyTree(repository, changeControl, new RestoreFileModification(file));
|
||||
modifyTree(repository, notes, new RestoreFileModification(file));
|
||||
}
|
||||
|
||||
private void modifyTree(
|
||||
Repository repository, ChangeControl changeControl, TreeModification treeModification)
|
||||
Repository repository, ChangeNotes notes, TreeModification treeModification)
|
||||
throws AuthException, IOException, OrmException, InvalidChangeOperationException,
|
||||
PermissionBackendException {
|
||||
assertCanEdit(changeControl);
|
||||
assertCanEdit(notes);
|
||||
|
||||
Optional<ChangeEdit> optionalChangeEdit = lookupChangeEdit(changeControl);
|
||||
PatchSet basePatchSet = getBasePatchSet(optionalChangeEdit, changeControl);
|
||||
Optional<ChangeEdit> optionalChangeEdit = lookupChangeEdit(notes);
|
||||
PatchSet basePatchSet = getBasePatchSet(optionalChangeEdit, notes);
|
||||
RevCommit basePatchSetCommit = lookupCommit(repository, basePatchSet);
|
||||
RevCommit baseCommit =
|
||||
optionalChangeEdit.map(ChangeEdit::getEditCommit).orElse(basePatchSetCommit);
|
||||
@@ -339,7 +329,7 @@ public class ChangeEditModifier {
|
||||
if (optionalChangeEdit.isPresent()) {
|
||||
updateEdit(repository, optionalChangeEdit.get(), newEditCommit, nowTimestamp);
|
||||
} 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.
|
||||
*
|
||||
* @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 treeModifications the modifications which should be applied
|
||||
* @return the resulting {@code ChangeEdit}
|
||||
@@ -361,15 +351,15 @@ public class ChangeEditModifier {
|
||||
*/
|
||||
public ChangeEdit combineWithModifiedPatchSetTree(
|
||||
Repository repository,
|
||||
ChangeControl changeControl,
|
||||
ChangeNotes notes,
|
||||
PatchSet patchSet,
|
||||
List<TreeModification> treeModifications)
|
||||
throws AuthException, IOException, InvalidChangeOperationException, MergeConflictException,
|
||||
OrmException, PermissionBackendException {
|
||||
assertCanEdit(changeControl);
|
||||
assertCanEdit(notes);
|
||||
|
||||
Optional<ChangeEdit> optionalChangeEdit = lookupChangeEdit(changeControl);
|
||||
ensureAllowedPatchSet(changeControl, optionalChangeEdit, patchSet);
|
||||
Optional<ChangeEdit> optionalChangeEdit = lookupChangeEdit(notes);
|
||||
ensureAllowedPatchSet(notes, optionalChangeEdit, patchSet);
|
||||
|
||||
RevCommit patchSetCommit = lookupCommit(repository, patchSet);
|
||||
ObjectId newTreeId = createNewTree(repository, patchSetCommit, treeModifications);
|
||||
@@ -392,11 +382,10 @@ public class ChangeEditModifier {
|
||||
if (optionalChangeEdit.isPresent()) {
|
||||
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)
|
||||
throws AuthException, PermissionBackendException {
|
||||
private void assertCanEdit(ChangeNotes notes) throws AuthException, PermissionBackendException {
|
||||
if (!currentUser.get().isIdentifiedUser()) {
|
||||
throw new AuthException("Authentication required");
|
||||
}
|
||||
@@ -404,7 +393,7 @@ public class ChangeEditModifier {
|
||||
permissionBackend
|
||||
.user(currentUser)
|
||||
.database(reviewDb)
|
||||
.change(changeControl.getNotes())
|
||||
.change(notes)
|
||||
.check(ChangePermission.ADD_PATCH_SET);
|
||||
} catch (AuthException denied) {
|
||||
throw new AuthException("edit not permitted", denied);
|
||||
@@ -412,7 +401,7 @@ public class ChangeEditModifier {
|
||||
}
|
||||
|
||||
private static void ensureAllowedPatchSet(
|
||||
ChangeControl changeControl, Optional<ChangeEdit> optionalChangeEdit, PatchSet patchSet)
|
||||
ChangeNotes notes, Optional<ChangeEdit> optionalChangeEdit, PatchSet patchSet)
|
||||
throws InvalidChangeOperationException {
|
||||
if (optionalChangeEdit.isPresent()) {
|
||||
ChangeEdit changeEdit = optionalChangeEdit.get();
|
||||
@@ -425,7 +414,7 @@ public class ChangeEditModifier {
|
||||
}
|
||||
} else {
|
||||
PatchSet.Id patchSetId = patchSet.getId();
|
||||
PatchSet.Id currentPatchSetId = changeControl.getChange().currentPatchSetId();
|
||||
PatchSet.Id currentPatchSetId = notes.getChange().currentPatchSetId();
|
||||
if (!patchSetId.equals(currentPatchSetId)) {
|
||||
throw new InvalidChangeOperationException(
|
||||
String.format(
|
||||
@@ -435,21 +424,19 @@ public class ChangeEditModifier {
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<ChangeEdit> lookupChangeEdit(ChangeControl changeControl)
|
||||
private Optional<ChangeEdit> lookupChangeEdit(ChangeNotes notes)
|
||||
throws AuthException, IOException {
|
||||
return changeEditUtil.byChange(changeControl);
|
||||
return changeEditUtil.byChange(notes);
|
||||
}
|
||||
|
||||
private PatchSet getBasePatchSet(
|
||||
Optional<ChangeEdit> optionalChangeEdit, ChangeControl changeControl) throws OrmException {
|
||||
private PatchSet getBasePatchSet(Optional<ChangeEdit> optionalChangeEdit, ChangeNotes notes)
|
||||
throws OrmException {
|
||||
Optional<PatchSet> editBasePatchSet = optionalChangeEdit.map(ChangeEdit::getBasePatchSet);
|
||||
return editBasePatchSet.isPresent()
|
||||
? editBasePatchSet.get()
|
||||
: lookupCurrentPatchSet(changeControl);
|
||||
return editBasePatchSet.isPresent() ? editBasePatchSet.get() : lookupCurrentPatchSet(notes);
|
||||
}
|
||||
|
||||
private PatchSet lookupCurrentPatchSet(ChangeControl changeControl) throws OrmException {
|
||||
return patchSetUtil.current(reviewDb.get(), changeControl.getNotes());
|
||||
private PatchSet lookupCurrentPatchSet(ChangeNotes notes) throws OrmException {
|
||||
return patchSetUtil.current(reviewDb.get(), notes);
|
||||
}
|
||||
|
||||
private static boolean isBasedOn(ChangeEdit changeEdit, PatchSet patchSet) {
|
||||
@@ -531,12 +518,12 @@ public class ChangeEditModifier {
|
||||
|
||||
private ChangeEdit createEdit(
|
||||
Repository repository,
|
||||
ChangeControl changeControl,
|
||||
ChangeNotes notes,
|
||||
PatchSet basePatchSet,
|
||||
ObjectId newEditCommitId,
|
||||
Timestamp timestamp)
|
||||
throws IOException, OrmException {
|
||||
Change change = changeControl.getChange();
|
||||
Change change = notes.getChange();
|
||||
String editRefName = getEditRefName(change, basePatchSet);
|
||||
updateReference(repository, editRefName, ObjectId.zeroId(), newEditCommitId, timestamp);
|
||||
reindex(change);
|
||||
|
||||
@@ -38,8 +38,8 @@ import com.google.gerrit.server.change.ChangeKindCache;
|
||||
import com.google.gerrit.server.change.PatchSetInserter;
|
||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||
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.NoSuchChangeException;
|
||||
import com.google.gerrit.server.update.BatchUpdate;
|
||||
import com.google.gerrit.server.update.BatchUpdateOp;
|
||||
import com.google.gerrit.server.update.RepoContext;
|
||||
@@ -70,10 +70,9 @@ import org.eclipse.jgit.revwalk.RevWalk;
|
||||
public class ChangeEditUtil {
|
||||
private final GitRepositoryManager gitManager;
|
||||
private final PatchSetInserter.Factory patchSetInserterFactory;
|
||||
private final ChangeControl.GenericFactory changeControlFactory;
|
||||
private final ChangeIndexer indexer;
|
||||
private final Provider<ReviewDb> db;
|
||||
private final Provider<CurrentUser> user;
|
||||
private final Provider<CurrentUser> userProvider;
|
||||
private final ChangeKindCache changeKindCache;
|
||||
private final PatchSetUtil psUtil;
|
||||
|
||||
@@ -81,40 +80,32 @@ public class ChangeEditUtil {
|
||||
ChangeEditUtil(
|
||||
GitRepositoryManager gitManager,
|
||||
PatchSetInserter.Factory patchSetInserterFactory,
|
||||
ChangeControl.GenericFactory changeControlFactory,
|
||||
ChangeIndexer indexer,
|
||||
Provider<ReviewDb> db,
|
||||
Provider<CurrentUser> user,
|
||||
Provider<CurrentUser> userProvider,
|
||||
ChangeKindCache changeKindCache,
|
||||
PatchSetUtil psUtil) {
|
||||
this.gitManager = gitManager;
|
||||
this.patchSetInserterFactory = patchSetInserterFactory;
|
||||
this.changeControlFactory = changeControlFactory;
|
||||
this.indexer = indexer;
|
||||
this.db = db;
|
||||
this.user = user;
|
||||
this.userProvider = userProvider;
|
||||
this.changeKindCache = changeKindCache;
|
||||
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.
|
||||
*
|
||||
* @param change
|
||||
* @param notes change notes of change to retrieve change edits for.
|
||||
* @return edit for this change for this user, if present.
|
||||
* @throws AuthException
|
||||
* @throws IOException
|
||||
* @throws OrmException
|
||||
* @throws AuthException if this is not a logged-in user.
|
||||
* @throws IOException if an error occurs.
|
||||
*/
|
||||
public Optional<ChangeEdit> byChange(Change change)
|
||||
throws AuthException, IOException, OrmException {
|
||||
try {
|
||||
return byChange(changeControlFactory.controlFor(db.get(), change, user.get()));
|
||||
} catch (NoSuchChangeException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
public Optional<ChangeEdit> byChange(ChangeNotes notes) throws AuthException, IOException {
|
||||
return byChange(notes, userProvider.get());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -122,17 +113,19 @@ public class ChangeEditUtil {
|
||||
*
|
||||
* <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.
|
||||
* @throws AuthException if this is not a logged-in user.
|
||||
* @throws IOException if an error occurs.
|
||||
*/
|
||||
public Optional<ChangeEdit> byChange(ChangeControl ctl) throws AuthException, IOException {
|
||||
if (!ctl.getUser().isIdentifiedUser()) {
|
||||
public Optional<ChangeEdit> byChange(ChangeNotes notes, CurrentUser user)
|
||||
throws AuthException, IOException {
|
||||
if (!user.isIdentifiedUser()) {
|
||||
throw new AuthException("Authentication required");
|
||||
}
|
||||
IdentifiedUser u = ctl.getUser().asIdentifiedUser();
|
||||
Change change = ctl.getChange();
|
||||
IdentifiedUser u = user.asIdentifiedUser();
|
||||
Change change = notes.getChange();
|
||||
try (Repository repo = gitManager.openRepository(change.getProject())) {
|
||||
int n = change.currentPatchSetId().get();
|
||||
String[] refNames = new String[n];
|
||||
@@ -146,7 +139,7 @@ public class ChangeEditUtil {
|
||||
}
|
||||
try (RevWalk rw = new RevWalk(repo)) {
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -244,13 +237,13 @@ public class ChangeEditUtil {
|
||||
indexer.index(db.get(), change);
|
||||
}
|
||||
|
||||
private PatchSet getBasePatchSet(ChangeControl ctl, Ref ref) throws IOException {
|
||||
private PatchSet getBasePatchSet(ChangeNotes notes, Ref ref) throws IOException {
|
||||
try {
|
||||
int pos = ref.getName().lastIndexOf("/");
|
||||
checkArgument(pos > 0, "invalid edit ref: %s", ref.getName());
|
||||
String psId = ref.getName().substring(pos + 1);
|
||||
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) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
|
||||
@@ -2440,7 +2440,7 @@ class ReceiveCommits {
|
||||
Optional<ChangeEdit> edit = null;
|
||||
|
||||
try {
|
||||
edit = editUtil.byChange(projectControl.controlFor(notes));
|
||||
edit = editUtil.byChange(notes, user);
|
||||
} catch (AuthException | IOException e) {
|
||||
logError("Cannot retrieve edit", e);
|
||||
return false;
|
||||
|
||||
@@ -270,7 +270,7 @@ public class PatchScriptFactory implements Callable<PatchScript> {
|
||||
}
|
||||
|
||||
private ObjectId getEditRev() throws AuthException, IOException, OrmException {
|
||||
edit = editReader.byChange(change);
|
||||
edit = editReader.byChange(control.getNotes());
|
||||
if (edit.isPresent()) {
|
||||
return edit.get().getEditCommit();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user