DS-Lab / src / main / java / dslab / protocol / dmtp / SingleDomainMessage.java
SingleDomainMessage.java
Raw
package dslab.protocol.dmtp;

import dslab.protocol.Message;
import dslab.routing.Address;
import dslab.routing.Domain;

import java.util.Collection;

import static dslab.protocol.MessageBuilder.aMessage;
import static dslab.util.Utils.listElements;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.toSet;

/**
 * A message where all recipients are from the same domain. This facilitates delivery.
 */
public class SingleDomainMessage extends Message {

    /**
     * @param message where all recipients are from the same domain
     */
    public SingleDomainMessage(Message message) {
        super(message);

        var recipientDomains = recipients.stream().map(Address::getDomain).collect(toSet());

        if (recipientDomains.size() != 1)
            throw new IllegalArgumentException("Expected " + message + " to have recipients from exactly one domain, " +
                    "but found " + recipientDomains.size() + ": " + listElements(recipientDomains));
    }

    /**
     * Splits the given {@link Message} with recipients from multiple domains into a collection of {@link SingleDomainMessage}s with
     * each having recipients of just a single domain. Other fields remain unchanged.
     * E.g. a message to a@foo.com, b@foo.com, c@bar.com is transformed into a collection of two messages,
     * one to a@foo.com,b@foo.com, the second to c@bar.com
     */
    public static Collection<SingleDomainMessage> split(Message message) {
        return message.getRecipients()
                .stream()
                .collect(groupingBy(Address::getDomain))
                .values()
                .stream()
                .map(recipients -> new SingleDomainMessage(aMessage(message).recipients(recipients).build()))
                .collect(toSet());
    }

    public Domain getRecipientDomain() {
        return recipients.iterator().next().getDomain();
    }
}