in server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/MatcherSplitter.java [80:185]
public List<Mail> split(Mail mail) throws MessagingException {
Collection<MailAddress> matchedRcpts = null;
Collection<MailAddress> origRcpts = new ArrayList<>(mail.getRecipients());
long start = System.currentTimeMillis();
Throwable ex = null;
TimeMetric timeMetric = metricFactory.timer(matcher.getClass().getSimpleName());
try {
List<Mail> mails = new ArrayList<>();
boolean fullMatch = false;
try (Closeable closeable =
MDCBuilder.create()
.addToContext(MDCBuilder.PROTOCOL, "MAILET")
.addToContext(MDCBuilder.ACTION, "MATCHER")
.addToContext(MDCBuilder.IP, mail.getRemoteAddr())
.addToContext(MDCBuilder.HOST, mail.getRemoteHost())
.addToContext("matcher", matcher.getMatcherInfo())
.addToContext("state", mail.getState())
.addToContext("mail", mail.getName())
.addToContext("recipients", ImmutableList.copyOf(mail.getRecipients()).toString())
.addToContext("sender", mail.getMaybeSender().asString())
.build()) {
// call the matcher
matchedRcpts = matcher.match(mail);
if (matchedRcpts == null) {
// In case the matcher returned null, create an empty
// Collection
matchedRcpts = new ArrayList<>(0);
} else if (matchedRcpts != mail.getRecipients()) {
// Make sure all the objects are MailAddress objects
ProcessorUtil.verifyMailAddresses(matchedRcpts);
}
} catch (Exception | NoClassDefFoundError me) {
ex = me;
if (onMatchException.equalsIgnoreCase("nomatch")) {
// In case the matcher returned null, create an empty
// Collection
LOGGER.warn("Encountered error while executing matcher {}. Matching none.", matcher, ex);
matchedRcpts = new ArrayList<>(0);
} else if (onMatchException.equalsIgnoreCase("matchall")) {
LOGGER.warn("Encountered error while executing matcher {}. matching all.", matcher, ex);
matchedRcpts = mail.getRecipients();
// no need to verify addresses
} else if (onMatchException.equalsIgnoreCase("propagate")) {
throw new RuntimeException(me);
} else {
ProcessorUtil.handleException(me, mail, matcher.getMatcherConfig().getMatcherName(), onMatchException, LOGGER);
}
}
// check if the matcher matched
if (matchedRcpts != null && !matchedRcpts.isEmpty()) {
List<MailAddress> rcpts = new ArrayList<>(mail.getRecipients());
for (MailAddress matchedRcpt : matchedRcpts) {
// loop through the recipients and remove the recipients
// that matched
rcpts.remove(matchedRcpt);
}
if (rcpts.isEmpty()) {
// all recipients matched
fullMatch = true;
} else {
mail.setRecipients(rcpts);
Mail newMail = MailImpl.duplicate(mail);
newMail.setRecipients(matchedRcpts);
newMail.setState(mail.getState());
// Set a header because the matcher matched. This can be
// used later when processing the route
newMail.setAttribute(new Attribute(MATCHER_MATCHED_ATTRIBUTE, AttributeValue.of(true)));
// add the new generated mail to the mails list
mails.add(newMail);
}
}
if (fullMatch) {
// Set a header because the matcher matched. This can be used
// later when processing the route
mail.setAttribute(new Attribute(MATCHER_MATCHED_ATTRIBUTE, AttributeValue.of(true)));
}
// add mailMsg to the mails list
mails.add(mail);
return mails;
} finally {
timeMetric.stopAndPublish();
long complete = System.currentTimeMillis() - start;
List<MailetProcessorListener> listeners = container.getListeners();
for (MailetProcessorListener listener : listeners) {
// need to check if its null or empty!
if (matchedRcpts == null || matchedRcpts.isEmpty()) {
listener.afterMatcher(matcher, mail.getName(), origRcpts, null, complete, ex);
} else {
listener.afterMatcher(matcher, mail.getName(), origRcpts, matchedRcpts, complete, ex);
}
}
}
}