DS-Lab / src / main / java / dslab / rmi / stub / ServerStub.java
ServerStub.java
Raw
package dslab.rmi.stub;

import dslab.protocol.Protocol;
import dslab.protocol.ProtocolException;
import dslab.rmi.channel.SocketChannel;
import dslab.rmi.serialize.IllegalCommandException;
import dslab.rmi.serialize.ServerSerializer;

import java.nio.channels.ClosedChannelException;
import java.util.logging.Logger;

import static java.lang.Thread.currentThread;
import static java.util.logging.Level.INFO;

public abstract class ServerStub<PROTOCOL extends Protocol> implements Runnable {

    private final PROTOCOL protocol;
    private final SocketChannel channel;
    private final ServerSerializer<PROTOCOL> serializer;

    private final Logger LOG = Logger.getLogger(getClass().getSimpleName());


    public ServerStub(SocketChannel channel, ServerSerializer<PROTOCOL> serializer, PROTOCOL protocol) {
        this.channel = channel;
        this.protocol = protocol;
        this.serializer = serializer;
        LOG.info("Init " + getClass().getSimpleName() + " with " + this.channel + " aka " + this.channel.getId());

    }

    @Override
    public void run() {
        try {
            try (channel) {
                channel.write(serializer.serialize(protocol));
                while (!currentThread().isInterrupted()) {
                    try {
                        var result = serializer.deserialize(channel.readLinesWhileReady()).apply(protocol);
                        channel.write(serializer.serialize(result));
                    } catch (ProtocolException e) {
                        channel.write(serializer.serialize(e));
                        if (e instanceof IllegalCommandException) {
                            LOG.log(INFO, e.getMessage() + " - Closing connection.");
                            break;
                        }
                    }
                }
            } finally {
                afterSession();
            }
        } catch (ClosedChannelException ignored) {} //Break out of while if client terminates connection
    }

    protected abstract void afterSession();
}