Package mireka.transmission.immediate

Source Code of mireka.transmission.immediate.MailToHostTransmitter

package mireka.transmission.immediate;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.concurrent.NotThreadSafe;

import mireka.address.Recipient;
import mireka.smtp.ClientFactory;
import mireka.smtp.EnhancedStatus;
import mireka.transmission.Mail;
import mireka.transmission.queuing.LogIdFactory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.subethamail.smtp.client.SMTPException;
import org.subethamail.smtp.client.SmartClient;

/**
* MailToHostTransmitter transmits a mail to a specific host specified by its IP
* address.
*/
@NotThreadSafe
class MailToHostTransmitter {
    private final Logger logger = LoggerFactory
            .getLogger(MailToHostTransmitter.class);
    private final ClientFactory clientFactory;
    private OutgoingConnectionsRegistry outgoingConnectionsRegistry;
    private final LogIdFactory logIdFactory;
    private final RemoteMta remoteMta;
    private Mail mail;

    public MailToHostTransmitter(ClientFactory clientFactory,
            OutgoingConnectionsRegistry outgoingConnectionsRegistry,
            LogIdFactory logIdFactory, RemoteMta remoteMta) {
        this.clientFactory = clientFactory;
        this.outgoingConnectionsRegistry = outgoingConnectionsRegistry;
        this.logIdFactory = logIdFactory;
        this.remoteMta = remoteMta;

    }

    /**
     * Delivers the mail to the SMTP server running on the specified host.
     *
     * @param inetAddress
     *            The receiving SMTP host. The name (if there is one) must
     *            already be resolved (using dnsJava).
     * @throws PostponeException
     *             if it has not even tried connecting to the host, because it
     *             is likely that the host is busy at this moment.
     */
    public void transmit(Mail mail, InetAddress inetAddress)
            throws SendException, RecipientsWereRejectedException,
            PostponeException {
        this.mail = mail;
        SmartClient smartClient = null;
        try {
            outgoingConnectionsRegistry.openConnection(inetAddress);
        } catch (PostponeException e) {
            e.setRemoteMta(remoteMta);
            throw e;
        }
        try {
            smartClient = clientFactory.create(inetAddress);
            smartClient.from(mail.from.getSmtpText());
            List<RecipientRejection> recipientRejections =
                    new ArrayList<RecipientRejection>();
            List<Recipient> acceptedRecipients = new ArrayList<Recipient>();
            for (Recipient recipient : mail.recipients) {
                try {
                    smartClient.to(recipient.sourceRouteStripped());
                    acceptedRecipients.add(recipient);
                } catch (SMTPException e) {
                    RemoteMtaErrorResponseException sendException =
                            new RemoteMtaErrorResponseException(e, remoteMta);
                    recipientRejections.add(new RecipientRejection(recipient,
                            sendException));
                    String logId = logIdFactory.next();
                    sendException.initLogId(logId);
                    logger.debug("Recipient " + recipient
                            + " was rejected/failed. Log-ID=" + logId
                            + ". Continuing with the next recipient if one "
                            + "exists. " + e.getResponse());
                }
            }
            if (acceptedRecipients.isEmpty()) {
                logger.debug("All recipients were rejected");
                throw new RecipientsWereRejectedException(recipientRejections);
            }
            smartClient.dataStart();
            writeDataTo(smartClient);
            smartClient.dataEnd();
            if (!recipientRejections.isEmpty())
                throw new RecipientsWereRejectedException(recipientRejections);
            else
                return;
        } catch (SMTPException e) {
            throw new RemoteMtaErrorResponseException(e, remoteMta);
        } catch (UnknownHostException e) {
            // impossible
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new SendException("Connection failed: " + e.toString(), e,
                    new EnhancedStatus(450, "4.4.0",
                            "No answer from host or bad connection"), remoteMta);
        } finally {
            if (smartClient != null) {
                smartClient.quit();
            }
            outgoingConnectionsRegistry.releaseConnection(inetAddress);
        }
    }

    private void writeDataTo(SmartClient smartClient) throws IOException {
        SmartClientOutputStreamAdapter out =
                new SmartClientOutputStreamAdapter(smartClient);
        mail.mailData.writeTo(out);
    }
}
TOP

Related Classes of mireka.transmission.immediate.MailToHostTransmitter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.