diff options
Diffstat (limited to 'gerrit-server/src/main/java/com/google/gerrit/server/changedetail/PublishDraft.java')
-rw-r--r-- | gerrit-server/src/main/java/com/google/gerrit/server/changedetail/PublishDraft.java | 130 |
1 files changed, 123 insertions, 7 deletions
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/changedetail/PublishDraft.java b/gerrit-server/src/main/java/com/google/gerrit/server/changedetail/PublishDraft.java index a71e12e7b3..22eae2d9fa 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/changedetail/PublishDraft.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/changedetail/PublishDraft.java @@ -15,12 +15,29 @@ package com.google.gerrit.server.changedetail; +import static com.google.gerrit.server.mail.MailUtil.getRecipientsFromApprovals; +import static com.google.gerrit.server.mail.MailUtil.getRecipientsFromFooters; + import com.google.gerrit.common.ChangeHooks; +import com.google.gerrit.common.data.LabelTypes; import com.google.gerrit.common.data.ReviewResult; +import com.google.gerrit.reviewdb.client.Account; import com.google.gerrit.reviewdb.client.Change; +import com.google.gerrit.reviewdb.client.ChangeMessage; import com.google.gerrit.reviewdb.client.PatchSet; +import com.google.gerrit.reviewdb.client.PatchSetApproval; +import com.google.gerrit.reviewdb.client.PatchSetInfo; import com.google.gerrit.reviewdb.server.ReviewDb; +import com.google.gerrit.server.ApprovalsUtil; import com.google.gerrit.server.ChangeUtil; +import com.google.gerrit.server.IdentifiedUser; +import com.google.gerrit.server.account.AccountResolver; +import com.google.gerrit.server.git.GitRepositoryManager; +import com.google.gerrit.server.mail.CreateChangeSender; +import com.google.gerrit.server.mail.MailUtil.MailRecipients; +import com.google.gerrit.server.mail.ReplacePatchSetSender; +import com.google.gerrit.server.patch.PatchSetInfoFactory; +import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException; import com.google.gerrit.server.project.ChangeControl; import com.google.gerrit.server.project.NoSuchChangeException; import com.google.gwtorm.server.AtomicUpdate; @@ -28,9 +45,22 @@ import com.google.gwtorm.server.OrmException; import com.google.inject.Inject; import com.google.inject.assistedinject.Assisted; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.revwalk.FooterLine; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.revwalk.RevWalk; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.Collections; +import java.util.List; import java.util.concurrent.Callable; public class PublishDraft implements Callable<ReviewResult> { + private static final Logger log = + LoggerFactory.getLogger(PublishDraft.class); public interface Factory { PublishDraft create(PatchSet.Id patchSetId); @@ -39,27 +69,47 @@ public class PublishDraft implements Callable<ReviewResult> { private final ChangeControl.Factory changeControlFactory; private final ReviewDb db; private final ChangeHooks hooks; + private final GitRepositoryManager repoManager; + private final PatchSetInfoFactory patchSetInfoFactory; + private final ApprovalsUtil approvalsUtil; + private final AccountResolver accountResolver; + private final CreateChangeSender.Factory createChangeSenderFactory; + private final ReplacePatchSetSender.Factory replacePatchSetFactory; private final PatchSet.Id patchSetId; @Inject - PublishDraft(ChangeControl.Factory changeControlFactory, - ReviewDb db, @Assisted final PatchSet.Id patchSetId, - final ChangeHooks hooks) { + PublishDraft(final ChangeControl.Factory changeControlFactory, + final ReviewDb db, final ChangeHooks hooks, + final GitRepositoryManager repoManager, + final PatchSetInfoFactory patchSetInfoFactory, + final ApprovalsUtil approvalsUtil, + final AccountResolver accountResolver, + final CreateChangeSender.Factory createChangeSenderFactory, + final ReplacePatchSetSender.Factory replacePatchSetFactory, + @Assisted final PatchSet.Id patchSetId) { this.changeControlFactory = changeControlFactory; this.db = db; this.hooks = hooks; + this.repoManager = repoManager; + this.patchSetInfoFactory = patchSetInfoFactory; + this.approvalsUtil = approvalsUtil; + this.accountResolver = accountResolver; + this.createChangeSenderFactory = createChangeSenderFactory; + this.replacePatchSetFactory = replacePatchSetFactory; this.patchSetId = patchSetId; } @Override - public ReviewResult call() throws NoSuchChangeException, OrmException { + public ReviewResult call() throws NoSuchChangeException, OrmException, + IOException, PatchSetInfoNotAvailableException { final ReviewResult result = new ReviewResult(); final Change.Id changeId = patchSetId.getParentKey(); result.setChangeId(changeId); final ChangeControl control = changeControlFactory.validateFor(changeId); + final LabelTypes labelTypes = control.getLabelTypes(); final PatchSet patch = db.patchSets().get(patchSetId); if (patch == null) { throw new NoSuchChangeException(changeId); @@ -74,7 +124,7 @@ public class PublishDraft implements Callable<ReviewResult> { result.addError(new ReviewResult.Error( ReviewResult.Error.Type.PUBLISH_NOT_PERMITTED)); } else { - final PatchSet updatedPatch = db.patchSets().atomicUpdate(patchSetId, + final PatchSet updatedPatchSet = db.patchSets().atomicUpdate(patchSetId, new AtomicUpdate<PatchSet>() { @Override public PatchSet update(PatchSet patchset) { @@ -95,11 +145,77 @@ public class PublishDraft implements Callable<ReviewResult> { } }); - if (!updatedPatch.isDraft() || updatedChange.getStatus() == Change.Status.NEW) { - hooks.doDraftPublishedHook(updatedChange, updatedPatch, db); + if (!updatedPatchSet.isDraft() || updatedChange.getStatus() == Change.Status.NEW) { + hooks.doDraftPublishedHook(updatedChange, updatedPatchSet, db); + + sendNotifications(control.getChange().getStatus() == Change.Status.DRAFT, + (IdentifiedUser) control.getCurrentUser(), updatedChange, updatedPatchSet, + labelTypes); } } return result; } + + private void sendNotifications(final boolean newChange, + final IdentifiedUser currentUser, final Change updatedChange, + final PatchSet updatedPatchSet, final LabelTypes labelTypes) + throws OrmException, IOException, PatchSetInfoNotAvailableException { + final Repository git = repoManager.openRepository(updatedChange.getProject()); + try { + final RevWalk revWalk = new RevWalk(git); + final RevCommit commit; + try { + commit = revWalk.parseCommit(ObjectId.fromString(updatedPatchSet.getRevision().get())); + } finally { + revWalk.release(); + } + final PatchSetInfo info = patchSetInfoFactory.get(commit, updatedPatchSet.getId()); + final List<FooterLine> footerLines = commit.getFooterLines(); + final Account.Id me = currentUser.getAccountId(); + final MailRecipients recipients = + getRecipientsFromFooters(accountResolver, updatedPatchSet, footerLines); + recipients.remove(me); + + if (newChange) { + approvalsUtil.addReviewers(db, labelTypes, updatedChange, updatedPatchSet, info, + recipients.getReviewers(), Collections.<Account.Id> emptySet()); + try { + CreateChangeSender cm = createChangeSenderFactory.create(updatedChange); + cm.setFrom(me); + cm.setPatchSet(updatedPatchSet, info); + cm.addReviewers(recipients.getReviewers()); + cm.addExtraCC(recipients.getCcOnly()); + cm.send(); + } catch (Exception e) { + log.error("Cannot send email for new change " + updatedChange.getId(), e); + } + } else { + final List<PatchSetApproval> patchSetApprovals = + db.patchSetApprovals().byChange(updatedChange.getId()).toList(); + final MailRecipients oldRecipients = + getRecipientsFromApprovals(patchSetApprovals); + approvalsUtil.addReviewers(db, labelTypes, updatedChange, updatedPatchSet, info, + recipients.getReviewers(), oldRecipients.getAll()); + final ChangeMessage msg = + new ChangeMessage(new ChangeMessage.Key(updatedChange.getId(), + ChangeUtil.messageUUID(db)), me, + updatedPatchSet.getCreatedOn(), updatedPatchSet.getId()); + msg.setMessage("Uploaded patch set " + updatedPatchSet.getPatchSetId() + "."); + try { + ReplacePatchSetSender cm = replacePatchSetFactory.create(updatedChange); + cm.setFrom(me); + cm.setPatchSet(updatedPatchSet, info); + cm.setChangeMessage(msg); + cm.addReviewers(recipients.getReviewers()); + cm.addExtraCC(recipients.getCcOnly()); + cm.send(); + } catch (Exception e) { + log.error("Cannot send email for new patch set " + updatedPatchSet.getId(), e); + } + } + } finally { + git.close(); + } + } } |