DS-Lab / src / main / java / dslab / rmi / serialize / dmtp / DmtpClientSerializer.java
DmtpClientSerializer.java
Raw
package dslab.rmi.serialize.dmtp;

import dslab.protocol.ProtocolException;
import dslab.rmi.serialize.ClientSerializer;
import dslab.rmi.serialize.Executors.ThrowingSupplier;
import dslab.rmi.serialize.ParseException;

import java.util.StringTokenizer;
import java.util.logging.Logger;

import static java.lang.Integer.parseInt;
import static java.util.Arrays.stream;

public class DmtpClientSerializer extends ClientSerializer {

    private static final Logger LOG = Logger.getLogger(DmtpClientSerializer.class.getSimpleName());

    public ThrowingSupplier<?, ? extends ProtocolException> deserialize(String response) throws ParseException {

        super.tokenizer = new StringTokenizer(response);

        switch (dmtpResponse(arg("command"))) {
            case ok: return ok(zeroOrMoreRemainingAsString("payload"));
            case error: return error(arg("code"), zeroOrMoreRemainingAsString("message"));
        }

        throw new IllegalStateException(); //never happens
    }

    private ThrowingSupplier<?, ParseException> ok(String payload) {
        var result = payload.isEmpty() ? null :
                     payload.matches("\\d+") ? parseInt(payload) :
                     payload;

        return () -> result;
    }

    private ThrowingSupplier<?, ProtocolException> error(String code, String message) throws ParseException {
        assertEndOfLine();
        var e = ProtocolException.from(code, message);
        return () -> {throw e;};
    }

    @Override
    protected String arg(String name) {
        try {
            return super.arg(name);
        } catch (ProtocolException e) {
            throw new IllegalStateException(e); //never happens
        }
    }

    @Override
    protected String oneOrMoreRemainingAsString(String name) {
        try {
            return super.oneOrMoreRemainingAsString(name);
        } catch (ProtocolException e) {
            throw new IllegalStateException(e); //never happens
        }
    }

    private DmtpResponse dmtpResponse(String command) {
        return stream(DmtpResponse.values())
                .filter(x -> x.name().equals(command))
                .findAny()
                .orElseThrow();
    }

    public enum DmtpResponse {ok, error}
}