package mireka.address.parser;
import java.text.ParseException;
import java.util.Locale;
import mireka.address.parser.ast.DomainPostmasterRecipientAST;
import mireka.address.parser.ast.DomainRemotePartAST;
import mireka.address.parser.ast.MailboxRecipientAST;
import mireka.address.parser.ast.PathAST;
import mireka.address.parser.ast.RecipientAST;
import mireka.address.parser.ast.SystemPostmasterRecipientAST;
import mireka.address.parser.base.CharParser;
import mireka.address.parser.base.CharScanner;
public class RecipientParser extends CharParser {
public RecipientParser(CharScanner charScanner) {
super(charScanner);
}
public RecipientParser(String source) {
super(source);
}
public RecipientAST parse() throws ParseException {
RecipientAST recipientAST = parseRecipient();
if (currentToken.ch != -1)
throw currentToken.otherSyntaxException("Superfluous characters "
+ "after recipient: {0}");
return recipientAST;
}
private RecipientAST parseRecipient() throws ParseException {
String DOMAIN_POSTMASTER_PREFIX = "<Postmaster@";
String SYSTEM_POSTMASTER_PREFIX = "<Postmaster>";
pushPosition();
if (inputEqualsIgnoreCase(DOMAIN_POSTMASTER_PREFIX)) {
PathAST pathAST = parsePath();
if (pathAST.mailboxAST.remotePartAST instanceof DomainRemotePartAST)
return new DomainPostmasterRecipientAST(popPosition(),
pathAST.mailboxAST);
else
return new MailboxRecipientAST(popPosition(), pathAST);
} else if (inputEqualsIgnoreCase(SYSTEM_POSTMASTER_PREFIX)) {
accept('<');
pushSpelling();
acceptThem(SYSTEM_POSTMASTER_PREFIX.length() - 2);
String postmasterSpelling = popSpelling();
accept('>');
return new SystemPostmasterRecipientAST(popPosition(), postmasterSpelling);
} else {
PathAST pathAST = parsePath();
return new MailboxRecipientAST(popPosition(), pathAST);
}
}
private boolean inputEqualsIgnoreCase(String s) {
String sLowerCase = s.toLowerCase(Locale.US);
return peekString(sLowerCase.length()).toLowerCase(Locale.US).equals(
sLowerCase);
}
private PathAST parsePath() throws ParseException {
scanner.pushBack(currentToken);
PathAST pathAST = new PathParser(scanner).parseLeft();
currentToken = scanner.scan();
return pathAST;
}
}