Merge "Make calculation of mail recipients for new changes/patchsets reusable"
This commit is contained in:
@@ -16,6 +16,8 @@ package com.google.gerrit.server.git;
|
||||
|
||||
import static com.google.gerrit.reviewdb.client.Change.INITIAL_PATCH_SET_ID;
|
||||
import static com.google.gerrit.server.git.MultiProgressMonitor.UNKNOWN;
|
||||
import static com.google.gerrit.server.mail.MailUtil.getRecipientsFromApprovals;
|
||||
import static com.google.gerrit.server.mail.MailUtil.getRecipientsFromFooters;
|
||||
import static org.eclipse.jgit.lib.Constants.R_HEADS;
|
||||
import static org.eclipse.jgit.transport.ReceiveCommand.Result.NOT_ATTEMPTED;
|
||||
import static org.eclipse.jgit.transport.ReceiveCommand.Result.OK;
|
||||
@@ -40,7 +42,6 @@ import com.google.gerrit.common.ChangeHooks;
|
||||
import com.google.gerrit.common.PageLinks;
|
||||
import com.google.gerrit.common.data.Capable;
|
||||
import com.google.gerrit.common.data.PermissionRule;
|
||||
import com.google.gerrit.common.errors.NoSuchAccountException;
|
||||
import com.google.gerrit.extensions.registration.DynamicSet;
|
||||
import com.google.gerrit.reviewdb.client.Account;
|
||||
import com.google.gerrit.reviewdb.client.Branch;
|
||||
@@ -68,6 +69,7 @@ import com.google.gerrit.server.git.validators.CommitValidationException;
|
||||
import com.google.gerrit.server.git.validators.CommitValidationListener;
|
||||
import com.google.gerrit.server.git.validators.CommitValidationMessage;
|
||||
import com.google.gerrit.server.mail.CreateChangeSender;
|
||||
import com.google.gerrit.server.mail.MailUtil.MailRecipients;
|
||||
import com.google.gerrit.server.mail.MergedSender;
|
||||
import com.google.gerrit.server.mail.ReplacePatchSetSender;
|
||||
import com.google.gerrit.server.patch.PatchSetInfoFactory;
|
||||
@@ -143,8 +145,6 @@ public class ReceiveCommits {
|
||||
private static final Pattern NEW_PATCHSET =
|
||||
Pattern.compile("^refs/changes/(?:[0-9][0-9]/)?([1-9][0-9]*)(?:/new)?$");
|
||||
|
||||
private static final FooterKey REVIEWED_BY = new FooterKey("Reviewed-by");
|
||||
private static final FooterKey TESTED_BY = new FooterKey("Tested-by");
|
||||
private static final FooterKey CHANGE_ID = new FooterKey("Change-Id");
|
||||
|
||||
private static final String COMMAND_REJECTION_MESSAGE_FOOTER =
|
||||
@@ -741,16 +741,6 @@ public class ReceiveCommits {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
private Account.Id toAccountId(final String nameOrEmail) throws OrmException,
|
||||
NoSuchAccountException {
|
||||
final Account a = accountResolver.findByNameOrEmail(nameOrEmail);
|
||||
if (a == null) {
|
||||
throw new NoSuchAccountException("\"" + nameOrEmail
|
||||
+ "\" is not registered");
|
||||
}
|
||||
return a.getId();
|
||||
}
|
||||
|
||||
private void parseCommands(final Collection<ReceiveCommand> commands) {
|
||||
for (final ReceiveCommand cmd : commands) {
|
||||
if (cmd.getResult() != NOT_ATTEMPTED) {
|
||||
@@ -1385,25 +1375,10 @@ public class ReceiveCommits {
|
||||
|
||||
private void insertChange(ReviewDb db) throws OrmException {
|
||||
final Account.Id me = currentUser.getAccountId();
|
||||
final Set<Account.Id> reviewers = new HashSet<Account.Id>(reviewerId);
|
||||
final Set<Account.Id> cc = new HashSet<Account.Id>(ccId);
|
||||
final List<FooterLine> footerLines = commit.getFooterLines();
|
||||
if (!ps.isDraft()) {
|
||||
for (final FooterLine footerLine : footerLines) {
|
||||
try {
|
||||
if (isReviewer(footerLine)) {
|
||||
reviewers.add(toAccountId(footerLine.getValue().trim()));
|
||||
} else if (footerLine.matches(FooterKey.CC)) {
|
||||
cc.add(toAccountId(footerLine.getValue().trim()));
|
||||
}
|
||||
} catch (NoSuchAccountException e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
reviewers.remove(me);
|
||||
cc.remove(me);
|
||||
cc.removeAll(reviewers);
|
||||
final MailRecipients recipients = new MailRecipients(reviewerId, ccId);
|
||||
recipients.add(getRecipientsFromFooters(accountResolver, ps, footerLines));
|
||||
recipients.remove(me);
|
||||
|
||||
db.changes().beginTransaction(change.getId());
|
||||
try {
|
||||
@@ -1412,7 +1387,7 @@ public class ReceiveCommits {
|
||||
db.changes().insert(Collections.singleton(change));
|
||||
ChangeUtil.updateTrackingIds(db, change, trackingFooters, footerLines);
|
||||
approvalsUtil.addReviewers(db, change, ps, info,
|
||||
reviewers, Collections.<Account.Id> emptySet());
|
||||
recipients.getReviewers(), Collections.<Account.Id> emptySet());
|
||||
db.commit();
|
||||
} finally {
|
||||
db.rollback();
|
||||
@@ -1430,8 +1405,8 @@ public class ReceiveCommits {
|
||||
createChangeSenderFactory.create(change);
|
||||
cm.setFrom(me);
|
||||
cm.setPatchSet(ps, info);
|
||||
cm.addReviewers(reviewers);
|
||||
cm.addExtraCC(cc);
|
||||
cm.addReviewers(recipients.getReviewers());
|
||||
cm.addExtraCC(recipients.getCcOnly());
|
||||
cm.send();
|
||||
} catch (Exception e) {
|
||||
log.error("Cannot send email for new change " + change.getId(), e);
|
||||
@@ -1446,13 +1421,6 @@ public class ReceiveCommits {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isReviewer(final FooterLine candidateFooterLine) {
|
||||
return candidateFooterLine.matches(FooterKey.SIGNED_OFF_BY)
|
||||
|| candidateFooterLine.matches(FooterKey.ACKED_BY)
|
||||
|| candidateFooterLine.matches(REVIEWED_BY)
|
||||
|| candidateFooterLine.matches(TESTED_BY);
|
||||
}
|
||||
|
||||
private void preparePatchSetsForReplace() {
|
||||
try {
|
||||
readChangesForReplace();
|
||||
@@ -1698,28 +1666,10 @@ public class ReceiveCommits {
|
||||
|
||||
PatchSet.Id insertPatchSet(ReviewDb db) throws OrmException {
|
||||
final Account.Id me = currentUser.getAccountId();
|
||||
final Set<Account.Id> reviewers = new HashSet<Account.Id>(reviewerId);
|
||||
final Set<Account.Id> cc = new HashSet<Account.Id>(ccId);
|
||||
final List<FooterLine> footerLines = newCommit.getFooterLines();
|
||||
if (!newPatchSet.isDraft()) {
|
||||
for (final FooterLine footerLine : footerLines) {
|
||||
try {
|
||||
if (isReviewer(footerLine)) {
|
||||
reviewers.add(toAccountId(footerLine.getValue().trim()));
|
||||
} else if (footerLine.matches(FooterKey.CC)) {
|
||||
cc.add(toAccountId(footerLine.getValue().trim()));
|
||||
}
|
||||
} catch (NoSuchAccountException e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
reviewers.remove(me);
|
||||
cc.remove(me);
|
||||
cc.removeAll(reviewers);
|
||||
|
||||
final Set<Account.Id> oldReviewers = new HashSet<Account.Id>();
|
||||
final Set<Account.Id> oldCC = new HashSet<Account.Id>();
|
||||
final MailRecipients recipients = new MailRecipients(reviewerId, ccId);
|
||||
recipients.add(getRecipientsFromFooters(accountResolver, newPatchSet, footerLines));
|
||||
recipients.remove(me);
|
||||
|
||||
db.changes().beginTransaction(change.getId());
|
||||
try {
|
||||
@@ -1739,22 +1689,11 @@ public class ReceiveCommits {
|
||||
|
||||
List<PatchSetApproval> patchSetApprovals =
|
||||
approvalsUtil.copyVetosToPatchSet(db, newPatchSet.getId());
|
||||
|
||||
final Set<Account.Id> haveApprovals = new HashSet<Account.Id>();
|
||||
oldReviewers.clear();
|
||||
oldCC.clear();
|
||||
|
||||
for (PatchSetApproval a : patchSetApprovals) {
|
||||
haveApprovals.add(a.getAccountId());
|
||||
if (a.getValue() != 0) {
|
||||
oldReviewers.add(a.getAccountId());
|
||||
} else {
|
||||
oldCC.add(a.getAccountId());
|
||||
}
|
||||
}
|
||||
|
||||
final MailRecipients oldRecipients =
|
||||
getRecipientsFromApprovals(patchSetApprovals);
|
||||
approvalsUtil.addReviewers(db, change, newPatchSet, info,
|
||||
reviewers, haveApprovals);
|
||||
recipients.getReviewers(), oldRecipients.getAll());
|
||||
recipients.add(oldRecipients);
|
||||
|
||||
msg =
|
||||
new ChangeMessage(new ChangeMessage.Key(change.getId(), ChangeUtil
|
||||
@@ -1829,10 +1768,8 @@ public class ReceiveCommits {
|
||||
cm.setFrom(me);
|
||||
cm.setPatchSet(newPatchSet, info);
|
||||
cm.setChangeMessage(msg);
|
||||
cm.addReviewers(reviewers);
|
||||
cm.addExtraCC(cc);
|
||||
cm.addReviewers(oldReviewers);
|
||||
cm.addExtraCC(oldCC);
|
||||
cm.addReviewers(recipients.getReviewers());
|
||||
cm.addExtraCC(recipients.getCcOnly());
|
||||
cm.send();
|
||||
} catch (Exception e) {
|
||||
log.error("Cannot send email for new patch set " + newPatchSet.getId(), e);
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
// Copyright (C) 2013 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.mail;
|
||||
|
||||
import com.google.gerrit.common.errors.NoSuchAccountException;
|
||||
import com.google.gerrit.reviewdb.client.Account;
|
||||
import com.google.gerrit.reviewdb.client.PatchSet;
|
||||
import com.google.gerrit.reviewdb.client.PatchSetApproval;
|
||||
import com.google.gerrit.server.account.AccountResolver;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
|
||||
import org.eclipse.jgit.revwalk.FooterKey;
|
||||
import org.eclipse.jgit.revwalk.FooterLine;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class MailUtil {
|
||||
private static final FooterKey REVIEWED_BY = new FooterKey("Reviewed-by");
|
||||
private static final FooterKey TESTED_BY = new FooterKey("Tested-by");
|
||||
|
||||
public static MailRecipients getRecipientsFromFooters(
|
||||
final AccountResolver accountResolver, final PatchSet ps,
|
||||
final List<FooterLine> footerLines) throws OrmException {
|
||||
final MailRecipients recipients = new MailRecipients();
|
||||
if (!ps.isDraft()) {
|
||||
for (final FooterLine footerLine : footerLines) {
|
||||
try {
|
||||
if (isReviewer(footerLine)) {
|
||||
recipients.reviewers.add(toAccountId(accountResolver, footerLine
|
||||
.getValue().trim()));
|
||||
} else if (footerLine.matches(FooterKey.CC)) {
|
||||
recipients.cc.add(toAccountId(accountResolver, footerLine
|
||||
.getValue().trim()));
|
||||
}
|
||||
} catch (NoSuchAccountException e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
return recipients;
|
||||
}
|
||||
|
||||
public static MailRecipients getRecipientsFromApprovals(
|
||||
final List<PatchSetApproval> approvals) {
|
||||
final MailRecipients recipients = new MailRecipients();
|
||||
for (PatchSetApproval a : approvals) {
|
||||
if (a.getValue() != 0) {
|
||||
recipients.reviewers.add(a.getAccountId());
|
||||
} else {
|
||||
recipients.cc.add(a.getAccountId());
|
||||
}
|
||||
}
|
||||
return recipients;
|
||||
}
|
||||
|
||||
private static Account.Id toAccountId(final AccountResolver accountResolver,
|
||||
final String nameOrEmail) throws OrmException, NoSuchAccountException {
|
||||
final Account a = accountResolver.findByNameOrEmail(nameOrEmail);
|
||||
if (a == null) {
|
||||
throw new NoSuchAccountException("\"" + nameOrEmail
|
||||
+ "\" is not registered");
|
||||
}
|
||||
return a.getId();
|
||||
}
|
||||
|
||||
private static boolean isReviewer(final FooterLine candidateFooterLine) {
|
||||
return candidateFooterLine.matches(FooterKey.SIGNED_OFF_BY)
|
||||
|| candidateFooterLine.matches(FooterKey.ACKED_BY)
|
||||
|| candidateFooterLine.matches(REVIEWED_BY)
|
||||
|| candidateFooterLine.matches(TESTED_BY);
|
||||
}
|
||||
|
||||
public static class MailRecipients {
|
||||
private final Set<Account.Id> reviewers;
|
||||
private final Set<Account.Id> cc;
|
||||
|
||||
public MailRecipients() {
|
||||
this.reviewers = new HashSet<Account.Id>();
|
||||
this.cc = new HashSet<Account.Id>();
|
||||
}
|
||||
|
||||
public MailRecipients(final Set<Account.Id> reviewers,
|
||||
final Set<Account.Id> cc) {
|
||||
this.reviewers = new HashSet<Account.Id>(reviewers);
|
||||
this.cc = new HashSet<Account.Id>(cc);
|
||||
}
|
||||
|
||||
public void add(final MailRecipients recipients) {
|
||||
reviewers.addAll(recipients.reviewers);
|
||||
cc.addAll(recipients.cc);
|
||||
}
|
||||
|
||||
public void remove(final Account.Id toRemove) {
|
||||
reviewers.remove(toRemove);
|
||||
cc.remove(toRemove);
|
||||
}
|
||||
|
||||
public Set<Account.Id> getReviewers() {
|
||||
return Collections.unmodifiableSet(reviewers);
|
||||
}
|
||||
|
||||
public Set<Account.Id> getCcOnly() {
|
||||
final Set<Account.Id> cc = new HashSet<Account.Id>(this.cc);
|
||||
cc.removeAll(reviewers);
|
||||
return Collections.unmodifiableSet(cc);
|
||||
}
|
||||
|
||||
public Set<Account.Id> getAll() {
|
||||
final Set<Account.Id> all =
|
||||
new HashSet<Account.Id>(reviewers.size() + cc.size());
|
||||
all.addAll(reviewers);
|
||||
all.addAll(cc);
|
||||
return Collections.unmodifiableSet(all);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user