All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.gerrit.acceptance.testsuite.change.PerPatchsetOperationsImpl Maven / Gradle / Ivy

There is a newer version: 3.11.0
Show newest version
// Copyright (C) 2020 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.gerrit.acceptance.testsuite.change;

import static com.google.gerrit.testing.TestActionRefUpdateContext.openTestRefUpdateContext;

import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.Comment.Status;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.entities.Patch;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.entities.Project;
import com.google.gerrit.entities.RobotComment;
import com.google.gerrit.extensions.client.Comment;
import com.google.gerrit.extensions.client.Comment.Range;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.server.CommentsUtil;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.IdentifiedUser.GenericFactory;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.notedb.ChangeUpdate;
import com.google.gerrit.server.update.BatchUpdate;
import com.google.gerrit.server.update.BatchUpdateOp;
import com.google.gerrit.server.update.ChangeContext;
import com.google.gerrit.server.update.UpdateException;
import com.google.gerrit.server.update.context.RefUpdateContext;
import com.google.gerrit.server.util.time.TimeUtil;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import java.io.IOException;
import java.time.Instant;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevWalk;

/**
 * The implementation of {@link PerPatchsetOperations}.
 *
 * 

There is only one implementation of {@link PerPatchsetOperations}. Nevertheless, we keep the * separation between interface and implementation to enhance clarity. */ public class PerPatchsetOperationsImpl implements PerPatchsetOperations { private final GitRepositoryManager repositoryManager; private final IdentifiedUser.GenericFactory userFactory; private final BatchUpdate.Factory batchUpdateFactory; private final CommentsUtil commentsUtil; private final ChangeNotes changeNotes; private final PatchSet.Id patchsetId; public interface Factory { PerPatchsetOperationsImpl create(ChangeNotes changeNotes, PatchSet.Id patchsetId); } @Inject private PerPatchsetOperationsImpl( GitRepositoryManager repositoryManager, GenericFactory userFactory, BatchUpdate.Factory batchUpdateFactory, CommentsUtil commentsUtil, @Assisted ChangeNotes changeNotes, @Assisted PatchSet.Id patchsetId) { this.repositoryManager = repositoryManager; this.userFactory = userFactory; this.batchUpdateFactory = batchUpdateFactory; this.commentsUtil = commentsUtil; this.changeNotes = changeNotes; this.patchsetId = patchsetId; } @Override public TestPatchset get() { PatchSet patchset = changeNotes.getPatchSets().get(patchsetId); return TestPatchset.builder().patchsetId(patchsetId).commitId(patchset.commitId()).build(); } @Override public TestCommentCreation.Builder newComment() { return TestCommentCreation.builder(this::createComment, Status.PUBLISHED); } @Override public TestCommentCreation.Builder newDraftComment() { return TestCommentCreation.builder(this::createComment, Status.DRAFT); } @Override public TestRobotCommentCreation.Builder newRobotComment() { return TestRobotCommentCreation.builder(this::createRobotComment); } private String createComment(TestCommentCreation commentCreation) throws IOException, RestApiException, UpdateException { Project.NameKey project = changeNotes.getProjectName(); try (RefUpdateContext ctx = openTestRefUpdateContext()) { try (Repository repository = repositoryManager.openRepository(project); ObjectInserter objectInserter = repository.newObjectInserter(); RevWalk revWalk = new RevWalk(objectInserter.newReader())) { Instant now = TimeUtil.now(); IdentifiedUser author = getAuthor(commentCreation); CommentAdditionOp commentAdditionOp = new CommentAdditionOp(commentCreation); try (BatchUpdate batchUpdate = batchUpdateFactory.create(project, author, now)) { batchUpdate.setRepository(repository, revWalk, objectInserter); batchUpdate.addOp(changeNotes.getChangeId(), commentAdditionOp); batchUpdate.execute(); } return commentAdditionOp.createdCommentUuid; } } } private IdentifiedUser getAuthor(TestCommentCreation commentCreation) { Account.Id authorId = commentCreation.author().orElse(changeNotes.getChange().getOwner()); return userFactory.create(authorId); } private IdentifiedUser getAuthor(TestRobotCommentCreation robotCommentCreation) { Account.Id authorId = robotCommentCreation.author().orElse(changeNotes.getChange().getOwner()); return userFactory.create(authorId); } private static Comment.Range toCommentRange(TestRange range) { Comment.Range commentRange = new Range(); commentRange.startLine = range.start().line(); commentRange.startCharacter = range.start().charOffset(); commentRange.endLine = range.end().line(); commentRange.endCharacter = range.end().charOffset(); return commentRange; } private class CommentAdditionOp implements BatchUpdateOp { private String createdCommentUuid; private final TestCommentCreation commentCreation; public CommentAdditionOp(TestCommentCreation commentCreation) { this.commentCreation = commentCreation; } @Override public boolean updateChange(ChangeContext context) { HumanComment comment = toNewComment(context, commentCreation); ChangeUpdate changeUpdate = context.getUpdate(patchsetId); changeUpdate.putComment(commentCreation.status(), comment); // For published comments, only the tag set on the ChangeUpdate (and not on the HumanComment) // matters. commentCreation.tag().ifPresent(changeUpdate::setTag); createdCommentUuid = comment.key.uuid; return true; } private HumanComment toNewComment(ChangeContext context, TestCommentCreation commentCreation) { String message = commentCreation.message().orElse("The text of a test comment."); String filePath = commentCreation.file().orElse(Patch.PATCHSET_LEVEL); short side = commentCreation.side().orElse(CommentSide.PATCHSET_COMMIT).getNumericSide(); Boolean unresolved = commentCreation.unresolved().orElse(null); String parentUuid = commentCreation.parentUuid().orElse(null); Instant createdOn = commentCreation.createdOn().orElse(context.getWhen()); HumanComment newComment = commentsUtil.newHumanComment( context.getNotes(), context.getUser(), createdOn, filePath, patchsetId, side, message, unresolved, parentUuid, null); // For draft comments, only the tag set on the HumanComment (and not on the ChangeUpdate) // matters. commentCreation.tag().ifPresent(tag -> newComment.tag = tag); commentCreation.line().ifPresent(line -> newComment.setLineNbrAndRange(line, null)); // Specification of range trumps explicit line specification. commentCreation .range() .map(PerPatchsetOperationsImpl::toCommentRange) .ifPresent(range -> newComment.setLineNbrAndRange(null, range)); commentsUtil.setCommentCommitId( newComment, context.getChange(), changeNotes.getPatchSets().get(patchsetId)); return newComment; } } private String createRobotComment(TestRobotCommentCreation robotCommentCreation) throws IOException, RestApiException, UpdateException { Project.NameKey project = changeNotes.getProjectName(); try (RefUpdateContext ctx = openTestRefUpdateContext()) { try (Repository repository = repositoryManager.openRepository(project); ObjectInserter objectInserter = repository.newObjectInserter(); RevWalk revWalk = new RevWalk(objectInserter.newReader())) { Instant now = TimeUtil.now(); IdentifiedUser author = getAuthor(robotCommentCreation); RobotCommentAdditionOp robotCommentAdditionOp = new RobotCommentAdditionOp(robotCommentCreation); try (BatchUpdate batchUpdate = batchUpdateFactory.create(project, author, now)) { batchUpdate.setRepository(repository, revWalk, objectInserter); batchUpdate.addOp(changeNotes.getChangeId(), robotCommentAdditionOp); batchUpdate.execute(); } return robotCommentAdditionOp.createdRobotCommentUuid; } } } private class RobotCommentAdditionOp implements BatchUpdateOp { private String createdRobotCommentUuid; private final TestRobotCommentCreation robotCommentCreation; public RobotCommentAdditionOp(TestRobotCommentCreation robotCommentCreation) { this.robotCommentCreation = robotCommentCreation; } @Override public boolean updateChange(ChangeContext context) { RobotComment robotComment = toNewRobotComment(context, robotCommentCreation); ChangeUpdate changeUpdate = context.getUpdate(patchsetId); changeUpdate.putRobotComment(robotComment); // For robot comments, only the tag set on the ChangeUpdate (and not on the RobotComment) // matters. robotCommentCreation.tag().ifPresent(changeUpdate::setTag); createdRobotCommentUuid = robotComment.key.uuid; return true; } private RobotComment toNewRobotComment( ChangeContext context, TestRobotCommentCreation robotCommentCreation) { String message = robotCommentCreation.message().orElse("The text of a test robot comment."); String filePath = robotCommentCreation.file().orElse(Patch.PATCHSET_LEVEL); short side = robotCommentCreation.side().orElse(CommentSide.PATCHSET_COMMIT).getNumericSide(); String robotId = robotCommentCreation.robotId().orElse("robot"); String robotRunId = robotCommentCreation.robotId().orElse("1"); RobotComment newRobotComment = commentsUtil.newRobotComment( context, filePath, patchsetId, side, message, robotId, robotRunId); // TODO(paiking): This should not be needed, as the tag only matters in ChangeUpdate. robotCommentCreation.tag().ifPresent(tag -> newRobotComment.tag = tag); robotCommentCreation.line().ifPresent(line -> newRobotComment.setLineNbrAndRange(line, null)); // Specification of range trumps explicit line specification. robotCommentCreation .range() .map(PerPatchsetOperationsImpl::toCommentRange) .ifPresent(range -> newRobotComment.setLineNbrAndRange(null, range)); robotCommentCreation .parentUuid() .ifPresent(parentUuid -> newRobotComment.parentUuid = parentUuid); robotCommentCreation.url().ifPresent(url -> newRobotComment.url = url); if (!robotCommentCreation.properties().isEmpty()) { newRobotComment.properties = robotCommentCreation.properties(); } commentsUtil.setCommentCommitId( newRobotComment, context.getChange(), changeNotes.getPatchSets().get(patchsetId)); return newRobotComment; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy