package dslab.rmi.serialize.dmtp; import dslab.protocol.ProtocolException; import dslab.protocol.dmtp.Dmtp; import dslab.rmi.serialize.Executors.DmtpExecutor; import dslab.rmi.serialize.IllegalCommandException; import dslab.rmi.serialize.ServerSerializer; import dslab.routing.Address; import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; import static java.util.Arrays.stream; public class DmtpServerSerializer extends ServerSerializer<Dmtp> { @Override public DmtpExecutor<?> deserialize(String request) throws ProtocolException { super.tokenizer = new StringTokenizer(request); switch (dmtpCommand(arg("command"))) { case begin: return begin(); case to: return to(varArg("recipient(s)")); case from: return from(arg("sender")); case subject: return subject(oneOrMoreRemainingAsString("subject")); case data: return data(oneOrMoreRemainingAsString("data")); case send: return send(); case hash: return hash(zeroOrMoreRemainingAsString("hash")); case quit: return quit(); default: throw new IllegalStateException("Unknown command in request '" + request + "'"); //never happens } } private DmtpExecutor<Void> hash(String hash) throws ProtocolException { assertEndOfLine(); String finalHash = hash.equals("null") ? null : hash; return dmtp -> { dmtp.hash(finalHash); return null; }; } private DmtpCommand dmtpCommand(String command) throws IllegalCommandException { return stream(DmtpCommand.values()) .filter(x -> x.name().equals(command)) .findAny() .orElseThrow(() -> new IllegalCommandException(command)); } private DmtpExecutor<Void> from(String sender) throws ProtocolException { assertEndOfLine(); return dmtp -> { dmtp.from(parseAddress(sender)); return null; }; } public enum DmtpCommand {begin, to, from, subject, data, send, hash, quit} private DmtpExecutor<String> quit() throws ProtocolException { assertEndOfLine(); return dmtp -> { dmtp.quit(); return "bye"; }; } private DmtpExecutor<Void> send() throws ProtocolException { assertEndOfLine(); return dmtp -> { dmtp.send(); return null; }; } private DmtpExecutor<Void> data(String data) throws ProtocolException { assertEndOfLine(); return dmtp -> { dmtp.data(data); return null; }; } private DmtpExecutor<Void> subject(String subject) throws ProtocolException { assertEndOfLine(); return dmtp -> { dmtp.subject(subject); return null; }; } private DmtpExecutor<String> begin() throws ProtocolException { assertEndOfLine(); return dmtp -> dmtp.begin() != null ? "starting over" : ""; } private DmtpExecutor<Integer> to(List<String> receivers) throws ProtocolException { assertEndOfLine(); List<Address> list = new ArrayList<>(); for (String receiver : receivers) { Address address = parseAddress(receiver); list.add(address); } return dmtp -> dmtp.to(list); } }