package mireka.forward;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import mireka.address.NullReversePath;
import mireka.address.Recipient;
import mireka.address.ReversePath;
import mireka.destination.Session;
import mireka.destination.SessionDestination;
import mireka.filter.RecipientContext;
import mireka.smtp.RejectExceptionExt;
import mireka.transmission.LocalMailSystemException;
import mireka.transmission.Mail;
import mireka.transmission.Transmitter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* An SrsDestination assigned to a recipient indicates that the mail must be
* forwarded to a remote address, which is specified in the Sender Rewriting
* Scheme (SRS) compatible local part of the recipient address. These mails are
* delivery status notifications related to a mail forwarded by this mail server
* previously.
*/
public class SrsDestination implements SessionDestination {
private final Logger logger = LoggerFactory.getLogger(SrsDestination.class);
private Srs srs;
/**
* The transmitter which will be used to redistribute the incoming mail to
* the encoded original source servers.
*/
private Transmitter transmitter;
@Override
public Session createSession() {
return new SessionImpl();
}
@Override
public String toString() {
return "SrsDestination";
}
/**
* @category GETSET
*/
public void setSrs(Srs srs) {
this.srs = srs;
}
/**
* @category GETSET
*/
public Srs getSrs() {
return srs;
}
/**
* @category GETSET
*/
public Transmitter getTransmitter() {
return transmitter;
}
/**
* @category GETSET
*/
public void setTransmitter(Transmitter transmitter) {
this.transmitter = transmitter;
}
private class SessionImpl implements Session {
private List<Recipient> sourceMailboxes = new ArrayList<Recipient>();
@Override
public void from(ReversePath from) throws RejectExceptionExt {
// do nothing
}
@Override
public void recipient(RecipientContext recipientContext)
throws RejectExceptionExt {
try {
Recipient originalSource =
srs.reverse(recipientContext.recipient);
sourceMailboxes.add(originalSource);
} catch (InvalidSrsException e) {
logger.debug("SRS reverse expansion failed. " + e.getMessage());
throw new RejectExceptionExt(e.getStatus());
}
}
@Override
public void data(Mail mail) throws RejectExceptionExt, IOException {
try {
if (!mail.from.isNull()) {
mail.from = new NullReversePath();
logger.debug("Valid SRS message is received with "
+ "non-null reverse path. This contradicts the "
+ "intended purpose of SRS. Mail will be "
+ "forwarded with null reverse path anyway.");
}
mail.recipients.clear();
mail.recipients.addAll(sourceMailboxes);
transmitter.transmit(mail);
logger.debug("SRS addresses was expanded and mail was "
+ "submitted to transmitter: {}", mail);
} catch (LocalMailSystemException e) {
logger.error("Cannot transmit mail", e);
throw new RejectExceptionExt(e.errorStatus());
}
}
@Override
public void done() {
// nothing to do
}
}
}