package mireka.address;
import java.text.ParseException;
import mireka.address.parser.RecipientParser;
import mireka.address.parser.RemotePartParser;
import mireka.address.parser.ReversePathParser;
import mireka.address.parser.ast.AddressLiteralRemotePartAST;
import mireka.address.parser.ast.DomainPostmasterRecipientAST;
import mireka.address.parser.ast.DomainRemotePartAST;
import mireka.address.parser.ast.MailboxAST;
import mireka.address.parser.ast.MailboxRecipientAST;
import mireka.address.parser.ast.NullReversePathAST;
import mireka.address.parser.ast.RealReversePathAST;
import mireka.address.parser.ast.ReversePathAST;
import mireka.address.parser.ast.SystemPostmasterRecipientAST;
/**
* MailAddressFactory creates mail address related objects from strings.
*/
public class MailAddressFactory {
/**
* Parses the specified string and creates a {@link Recipient} instance.
*
* @param recipientString
* the recipient parameter of the RCPT SMTP command, without the
* enclosing angle bracket.
*/
public mireka.address.Recipient createRecipient(String recipientString)
throws ParseException {
String recipientStringWithAngleBracket = "<" + recipientString + ">";
mireka.address.parser.ast.RecipientAST recipientAST =
new RecipientParser(recipientStringWithAngleBracket).parse();
if (recipientAST instanceof SystemPostmasterRecipientAST) {
SystemPostmasterRecipientAST systemPostmasterAST =
(SystemPostmasterRecipientAST) recipientAST;
return new GlobalPostmaster(systemPostmasterAST.postmasterSpelling);
} else if (recipientAST instanceof DomainPostmasterRecipientAST) {
DomainPostmasterRecipientAST domainPostmasterAST =
(DomainPostmasterRecipientAST) recipientAST;
Mailbox mailbox = createMailbox(domainPostmasterAST.mailboxAST);
return new DomainPostmaster(mailbox);
} else if (recipientAST instanceof MailboxRecipientAST) {
MailboxRecipientAST mailboxRecipientAST =
(MailboxRecipientAST) recipientAST;
Mailbox mailbox =
createMailbox(mailboxRecipientAST.pathAST.mailboxAST);
return new GenericRecipient(mailbox);
} else {
throw new RuntimeException("Assertion failed");
}
}
private Mailbox createMailbox(MailboxAST mailboxAST) {
LocalPart localPart = new LocalPart(mailboxAST.localPartAST.spelling);
RemotePart remotePart =
createRemotePartFromAST(mailboxAST.remotePartAST);
return new Mailbox(mailboxAST.spelling, localPart, remotePart);
}
public mireka.address.RemotePart createRemotePartFromAST(
mireka.address.parser.ast.RemotePartAST remotePartAST) {
RemotePart remotePart;
if (remotePartAST instanceof DomainRemotePartAST) {
DomainRemotePartAST domainRemotePartAST =
(DomainRemotePartAST) remotePartAST;
Domain domain = new Domain(domainRemotePartAST.spelling);
remotePart = new DomainPart(domain);
} else if (remotePartAST instanceof AddressLiteralRemotePartAST) {
AddressLiteralRemotePartAST addressLiteralRemotePartAST =
(AddressLiteralRemotePartAST) remotePartAST;
remotePart =
new AddressLiteral(addressLiteralRemotePartAST.spelling,
addressLiteralRemotePartAST.address);
} else {
throw new RuntimeException("Assertion failed");
}
return remotePart;
}
public Recipient createRecipientAlreadyVerified(String recipientString) {
try {
return createRecipient(recipientString);
} catch (ParseException e) {
throw new IllegalArgumentException("Unexpected exception", e);
}
}
/**
* Creates a {@link RemotePart} object by parsing the specified displayable
* text. Note that currently actual parsing of displayable text is not
* implemented, internationalized domain names must be specified in ASCII
* compatible text.
*/
public RemotePart createRemotePartFromDisplayableText(String displayableText) {
mireka.address.parser.ast.RemotePartAST remotePartAST;
try {
remotePartAST = new RemotePartParser(displayableText).parse();
} catch (ParseException e) {
throw new IllegalArgumentException(e);
}
return createRemotePartFromAST(remotePartAST);
}
public ReversePath createReversePath(String reversePathString)
throws ParseException {
String reversePathStringWithAngleBracket =
"<" + reversePathString + ">";
ReversePathAST reversePathAST =
new ReversePathParser(reversePathStringWithAngleBracket)
.parse();
if (reversePathAST instanceof NullReversePathAST) {
return new NullReversePath();
} else if (reversePathAST instanceof RealReversePathAST) {
RealReversePathAST realReversePathAST =
(RealReversePathAST) reversePathAST;
Mailbox mailbox =
createMailbox(realReversePathAST.pathAST.mailboxAST);
return new RealReversePath(mailbox);
} else {
throw new RuntimeException("Assertion failed");
}
}
public ReversePath createReversePathAlreadyVerified(String reversePathString) {
try {
return createReversePath(reversePathString);
} catch (ParseException e) {
throw new IllegalArgumentException("Unexpected exception", e);
}
}
public Recipient reversePath2Recipient(ReversePath reversePath) {
if (reversePath.isNull())
throw new IllegalArgumentException("Reverse path is null");
RealReversePath realReversePath = (RealReversePath) reversePath;
Mailbox mailbox = realReversePath.getMailbox();
// Convert the complete text, because postmaster@... is represented by a
// different Recipient subclass, namely DomainPostmaster, not the usual
// GenericRecipient.
return createRecipientAlreadyVerified(mailbox.getSmtpText());
}
}