Support project notification using To or CC

Some teams want to have new change notifications be CC'd
to a mailing list so that reply-all goes to the list.
Add notify.*.header = cc support to allow this usage.

Change-Id: I037b823a4127fe4d2ba0248e6be7f7efd7544b1c
This commit is contained in:
Shawn O. Pearce
2012-10-25 17:02:50 -07:00
parent 6738e5f340
commit aedcb7e808
10 changed files with 88 additions and 33 deletions

View File

@@ -322,16 +322,13 @@ public abstract class ChangeEmail extends OutgoingEmail {
}
}
/** BCC users and groups that want notification of events. */
protected void bccWatches(NotifyType type) {
/** Include users and groups that want notification of events. */
protected void includeWatchers(NotifyType type) {
try {
Watchers matching = getWatches(type);
for (Account.Id user : matching.accounts) {
add(RecipientType.BCC, user);
}
for (Address addr : matching.emails) {
add(RecipientType.BCC, addr);
}
add(RecipientType.TO, matching.to);
add(RecipientType.CC, matching.cc);
add(RecipientType.BCC, matching.bcc);
} catch (OrmException err) {
// Just don't CC everyone. Better to send a partial message to those
// we already have queued up then to fail deliver entirely to people
@@ -340,6 +337,16 @@ public abstract class ChangeEmail extends OutgoingEmail {
}
}
/** Add users or email addresses to the TO, CC, or BCC list. */
protected void add(RecipientType type, Watchers.List list) {
for (Account.Id user : list.accounts) {
add(type, user);
}
for (Address addr : list.emails) {
add(type, addr);
}
}
/** Returns all watches that are relevant */
protected final Watchers getWatches(NotifyType type) throws OrmException {
Watchers matching = new Watchers();
@@ -385,8 +392,25 @@ public abstract class ChangeEmail extends OutgoingEmail {
}
protected static class Watchers {
protected final Set<Account.Id> accounts = Sets.newHashSet();
protected final Set<Address> emails = Sets.newHashSet();
static class List {
protected final Set<Account.Id> accounts = Sets.newHashSet();
protected final Set<Address> emails = Sets.newHashSet();
}
protected final List to = new List();
protected final List cc = new List();
protected final List bcc = new List();
List list(NotifyConfig.Header header) {
switch (header) {
case TO:
return to;
case CC:
return cc;
default:
case BCC:
return bcc;
}
}
}
@SuppressWarnings("unchecked")
@@ -419,7 +443,7 @@ public abstract class ChangeEmail extends OutgoingEmail {
p = args.queryRewriter.get().rewrite(p);
}
if (p.match(changeData)) {
recursivelyAddAllAccounts(matching, group);
recursivelyAddAllAccounts(matching.list(nc.getHeader()), group);
}
}
@@ -430,16 +454,16 @@ public abstract class ChangeEmail extends OutgoingEmail {
Predicate<ChangeData> p = qb.parse(nc.getFilter());
p = args.queryRewriter.get().rewrite(p);
if (p.match(changeData)) {
matching.emails.addAll(nc.getAddresses());
matching.list(nc.getHeader()).emails.addAll(nc.getAddresses());
}
} else {
matching.emails.addAll(nc.getAddresses());
matching.list(nc.getHeader()).emails.addAll(nc.getAddresses());
}
}
}
private void recursivelyAddAllAccounts(Watchers matching, AccountGroup group)
throws OrmException {
private void recursivelyAddAllAccounts(Watchers.List matching,
AccountGroup group) throws OrmException {
Set<AccountGroup.Id> seen = Sets.newHashSet();
Queue<AccountGroup.Id> scan = Lists.newLinkedList();
scan.add(group.getId());
@@ -472,13 +496,13 @@ public abstract class ChangeEmail extends OutgoingEmail {
p = Predicate.and(qb.parse(w.getFilter()), p);
p = args.queryRewriter.get().rewrite(p);
if (p.match(changeData)) {
matching.accounts.add(w.getAccountId());
matching.bcc.accounts.add(w.getAccountId());
}
} catch (QueryParseException e) {
// Ignore broken filter expressions.
}
} else if (p.match(changeData)) {
matching.accounts.add(w.getAccountId());
matching.bcc.accounts.add(w.getAccountId());
}
}