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

com.google.gerrit.server.PublishCommentsOp Maven / Gradle / Ivy

There is a newer version: 3.11.0-rc3
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.server;

import com.google.common.collect.ImmutableMap;
import com.google.gerrit.entities.ChangeMessage;
import com.google.gerrit.entities.HumanComment;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.entities.Project;
import com.google.gerrit.exceptions.StorageException;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
import com.google.gerrit.server.change.EmailReviewComments;
import com.google.gerrit.server.change.NotifyResolver;
import com.google.gerrit.server.extensions.events.CommentAdded;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.notedb.ChangeUpdate;
import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gerrit.server.update.BatchUpdateOp;
import com.google.gerrit.server.update.ChangeContext;
import com.google.gerrit.server.update.CommentsRejectedException;
import com.google.gerrit.server.update.Context;
import com.google.gerrit.server.update.RepoView;
import com.google.gerrit.server.util.LabelVote;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * A {@link BatchUpdateOp} that can be used to publish draft comments
 *
 * 

This class uses the {@link PublishCommentUtil} to publish draft comments and fires the * necessary event for this. */ public class PublishCommentsOp implements BatchUpdateOp { private final PatchSetUtil psUtil; private final ChangeNotes.Factory changeNotesFactory; private final ChangeMessagesUtil cmUtil; private final CommentAdded commentAdded; private final CommentsUtil commentsUtil; private final EmailReviewComments.Factory email; private final List labelDelta = new ArrayList<>(); private final Project.NameKey projectNameKey; private final PatchSet.Id psId; private final PublishCommentUtil publishCommentUtil; private List comments = new ArrayList<>(); private ChangeMessage message; private IdentifiedUser user; public interface Factory { PublishCommentsOp create(PatchSet.Id psId, Project.NameKey projectNameKey); } @Inject public PublishCommentsOp( ChangeNotes.Factory changeNotesFactory, ChangeMessagesUtil cmUtil, CommentAdded commentAdded, CommentsUtil commentsUtil, EmailReviewComments.Factory email, PatchSetUtil psUtil, PublishCommentUtil publishCommentUtil, @Assisted PatchSet.Id psId, @Assisted Project.NameKey projectNameKey) { this.cmUtil = cmUtil; this.changeNotesFactory = changeNotesFactory; this.commentAdded = commentAdded; this.commentsUtil = commentsUtil; this.email = email; this.psId = psId; this.publishCommentUtil = publishCommentUtil; this.psUtil = psUtil; this.projectNameKey = projectNameKey; } @Override public boolean updateChange(ChangeContext ctx) throws ResourceConflictException, UnprocessableEntityException, IOException, PatchListNotAvailableException, CommentsRejectedException { user = ctx.getIdentifiedUser(); comments = commentsUtil.draftByChangeAuthor(ctx.getNotes(), ctx.getUser().getAccountId()); // PublishCommentsOp should update a separate ChangeUpdate Object than the one used by other ops // For example, with the "publish comments on PS upload" workflow, // There are 2 ops: ReplaceOp & PublishCommentsOp, where each updates its own ChangeUpdate // This is required since // 1. a ChangeUpdate has only 1 change message // 2. Each ChangeUpdate results in 1 commit in NoteDb // We do it this way so that the execution results in 2 different commits in NoteDb ChangeUpdate changeUpdate = ctx.getDistinctUpdate(psId); publishCommentUtil.publish(ctx, changeUpdate, comments, null); return insertMessage(ctx, changeUpdate); } @Override public void postUpdate(Context ctx) { if (message == null || comments.isEmpty()) { return; } ChangeNotes changeNotes = changeNotesFactory.createChecked(projectNameKey, psId.changeId()); PatchSet ps = psUtil.get(changeNotes, psId); NotifyResolver.Result notify = ctx.getNotify(changeNotes.getChangeId()); if (notify.shouldNotify()) { RepoView repoView; try { repoView = ctx.getRepoView(); } catch (IOException ex) { throw new StorageException( String.format("Repository %s not found", ctx.getProject().get()), ex); } email .create(notify, changeNotes, ps, user, message, comments, null, labelDelta, repoView) .sendAsync(); } commentAdded.fire( changeNotes.getChange(), ps, ctx.getAccount(), message.getMessage(), ImmutableMap.of(), ImmutableMap.of(), ctx.getWhen()); } private boolean insertMessage(ChangeContext ctx, ChangeUpdate changeUpdate) { StringBuilder buf = new StringBuilder(); if (comments.size() == 1) { buf.append("\n\n(1 comment)"); } else if (comments.size() > 1) { buf.append(String.format("\n\n(%d comments)", comments.size())); } if (buf.length() == 0) { return false; } message = ChangeMessagesUtil.newMessage( psId, user, ctx.getWhen(), "Patch Set " + psId.get() + ":" + buf, null); cmUtil.addChangeMessage(changeUpdate, message); return true; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy