Skip to content

Instantly share code, notes, and snippets.

@tyriis
Last active November 12, 2018 22:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tyriis/c34bacda8b8b6ad3f59c4f771adc50b4 to your computer and use it in GitHub Desktop.
Save tyriis/c34bacda8b8b6ad3f59c4f771adc50b4 to your computer and use it in GitHub Desktop.
package dslab.DMTP;
import dslab.entities.Message;
import dslab.entities.User;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class DMTPWorker extends Thread {
static final String DMTP_GREETING = "ok DMTP";
static final String DMTP_OK = "ok";
static final String DMTP_BYE = "ok bye";
static final String DMTP_PROTOCOL_ERROR = "error protocol error";
private Socket socket;
private PrintWriter printWriter;
private Message message;
DMTPWorker(Socket socket) {
this.socket = socket;
}
public void run() {
BufferedReader bufferedReader;
try {
bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
printWriter = new PrintWriter(socket.getOutputStream(), true);
} catch (IOException e) {
// interrupted exit!
e.printStackTrace();
return;
}
send(DMTP_GREETING);
while (true) {
if (socket.isClosed()) {
break;
}
try {
if (!handleInput(bufferedReader.readLine())) {
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
exit();
}
private Boolean handleInput(String input) {
if (input == null) {
// noop
return true;
}
String command = input.split("\\s")[0];
Method handler;
String value = input.substring(command.length());
try {
handler = value.isEmpty()
? this.getClass().getDeclaredMethod(command.concat("Handler"))
: this.getClass().getDeclaredMethod(command.concat("Handler"), String.class);
} catch (NoSuchMethodException e) {
send(DMTP_PROTOCOL_ERROR);
// invalid command!
e.printStackTrace();
return false;
}
try {
return value.isEmpty()
? (Boolean)handler.invoke(this)
: (Boolean)handler.invoke(this, value);
} catch (IllegalAccessException | InvocationTargetException e) {
// this should never happen, anyway
e.printStackTrace();
}
return true;
}
private Boolean beginHandler() {
send(DMTP_OK);
message = new Message();
return true;
}
private Boolean toHandler(String input) {
if (message == null) {
send(DMTP_PROTOCOL_ERROR);
return false;
}
List<User> to = new ArrayList<>();
for (String address: input.split(",")) {
to.add(new User(address));
}
// validate sender list
message.setTo(to);
send(DMTP_OK);
return true;
}
private Boolean fromHandler(String from) {
if (message == null) {
send(DMTP_PROTOCOL_ERROR);
return false;
}
// validate from
message.setFrom(new User(from));
send(DMTP_OK);
return true;
}
private Boolean subjectHandler(String subject) {
if (message == null) {
send(DMTP_PROTOCOL_ERROR);
return false;
}
// validate subject
message.setSubject(subject);
send(DMTP_OK);
return true;
}
private Boolean dataHandler(String data) {
if (message == null) {
send(DMTP_PROTOCOL_ERROR);
return false;
}
// validate data
message.setData(data);
send(DMTP_OK);
return true;
}
private Boolean sendHandler() {
// check if ready to send
send(DMTP_OK);
return true;
}
private Boolean quitHandler() {
send(DMTP_BYE);
exit();
return true;
}
private void send(String output) {
printWriter.println(output);
}
private void exit() {
if (socket.isClosed()) {
return;
}
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment