DS-Lab / src / main / java / dslab / mailbox / MailboxManager.java
MailboxManager.java
Raw
package dslab.mailbox;

import dslab.authentication.AuthenticationService;
import dslab.authentication.User;
import dslab.protocol.Message;
import dslab.routing.Address;
import dslab.routing.AddressResolutionException;
import dslab.routing.DeliveryService;
import dslab.routing.Domain;

import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

import static dslab.util.Utils.listElements;
import static java.util.function.Function.identity;
import static java.util.stream.Collectors.*;

/**
 * Manages the mailboxes for all users on a server.
 */
public class MailboxManager implements DeliveryService {

    private final Domain home;

    private final Map<User, Mailbox> mailboxes;
    private final AuthenticationService authenticationService;
    private static final Logger LOG = Logger.getLogger(MailboxManager.class.getSimpleName());

    public MailboxManager(Domain home, AuthenticationService authenticationService) {
        this.authenticationService = authenticationService;
        this.home = home;
        mailboxes = this.authenticationService
                .getUsers()
                .stream()
                .collect(toConcurrentMap(identity(), Mailbox::new));
    }

    public Message getMessage(Integer messageId) throws MessageNotFoundException {
        return getMailbox(authenticationService.getLoggedInUser()).get(messageId);
    }

    public Mailbox getMailbox(User user) {
        if (!hasMailbox(user))
            throw new IllegalArgumentException("The user " + user + " doesn't exist");

        return mailboxes.get(user);

    }

    public boolean hasMailbox(User user) {
        return mailboxes.containsKey(user);
    }

    public void deleteMessage(Integer messageId) throws MessageNotFoundException {
        var loggedInUser = authenticationService.getLoggedInUser();
        mailboxes.get(loggedInUser).deleteMessage(messageId);
    }

    @Override
    public void deliver(Message message) {

        for (Address recipient : message.getRecipients())
            for (var entry : mailboxes.entrySet())
                if (entry.getKey().getAddress().equals(recipient)) {
                    entry.getValue().put(message);
                }
        LOG.info("Message sent: " + message);
    }

    /**
     * @return the number of addresses that this mailbox will store
     * @throws AddressResolutionException if there are addresses that belong to this domain
     *                                    of which the server doesn't recognize the user part
     */
    @Override
    public Integer validateAddresses(List<Address> addresses) throws AddressResolutionException {
        var addressesManagedByThisServer =
                addresses.stream().filter(address -> address.getDomain().equals(home)).collect(toList());

        //see assignment 1, sec. 2.5 'accepting messages'
        if (addressesManagedByThisServer.size() == 0)
            throw new AddressResolutionException("None of the addresses in " +
                    listElements(addresses) + " are part of the home domain " + home);

        var unknownAddresses = addressesManagedByThisServer.stream()
                .filter(x -> !authenticationService.knows(x))
                .map(Address::toString)
                .collect(joining(","));

        if (!unknownAddresses.isEmpty()) {
            LOG.info("User part of " + unknownAddresses + " is illegal" +
                    "in list of addresses " + listElements(addresses));
            throw new AddressResolutionException("The addresses " + unknownAddresses + " could not be resolved");
        }

        return addressesManagedByThisServer.size();
    }
}