public List split()

in server/mailet/mailetcontainer-impl/src/main/java/org/apache/james/mailetcontainer/impl/MatcherSplitter.java [79:184]


    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);
                }
            }
        }
    }