package bgu.bio.server.general.protocol;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import bgu.bio.algorithms.alignment.EditDistance;
import bgu.bio.com.protocol.AsyncServerProtocol;
import bgu.bio.io.file.json.JSONException;
import bgu.bio.io.file.json.JSONObject;
import bgu.bio.util.IdentityEditDistanceScoringMatrix;
import bgu.bio.util.alphabet.RnaAlphabet;
public class ScriptProtocol implements AsyncServerProtocol {
private boolean _shouldClose = false;
private boolean _connectionTerminated = false;
private final ScriptProtocolData data;
public ScriptProtocol(ScriptProtocolData data) {
this.data = data;
}
@Override
public void connectionTerminated() {
this._connectionTerminated = true;
}
@Override
public boolean isEnd(String msg) {
try {
JSONObject obj = new JSONObject(msg);
String command = obj.getString("command");
return command.equals("terminate");
} catch (JSONException ex) {
ex.printStackTrace();
}
return false;
}
@Override
public String processMessage(String msg) {
try {
if (this._connectionTerminated) {
return "{\"message\":\"TERM\"}";
}
if (this.isEnd(msg)) {
this._shouldClose = true;
return "{\"message\":\"TERM\"}";
}
JSONObject obj = new JSONObject(msg);
String command = obj.getString("command");
JSONObject result = new JSONObject();
if (command.equals("script.reverse")) {
String str1 = obj.optString("string1");
if (str1 == null)
return error("got no string");
StringBuilder sb = new StringBuilder();
for (int i = str1.length() - 1; i >= 0; i--) {
sb.append(str1.charAt(i));
}
result.put("command", "OK");
result.put("result", sb.toString());
return result.toString();
} else if (command.equals("script.complement")) {
String str1 = obj.optString("string1");
boolean rev = obj.optBoolean("reverse");
if (str1 == null)
return error("got no string");
if (rev) {
StringBuilder sb = new StringBuilder();
for (int i = str1.length() - 1; i >= 0; i--) {
sb.append(str1.charAt(i));
}
str1 = sb.toString();
}
RnaAlphabet alphabet = RnaAlphabet.getInstance();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str1.length(); i++) {
sb.append(alphabet.complement(str1.charAt(i)));
}
result.put("command", "OK");
result.put("result", sb.toString());
return result.toString();
} else if (command.equals("script.ed")) {
String str1 = obj.optString("string1").toUpperCase();
String str2 = obj.optString("string2").toUpperCase();
EditDistance ed = new EditDistance(str1, str2,
new IdentityEditDistanceScoringMatrix());
if (str1 == null || str2 == null)
return error("got no strings");
ed.buildMatrix();
int score = (int) ed.getAlignmentScore();
String[] res = ed.printAlignments();
result.put("command", "OK");
result.put("score", score);
result.put("line1", res[0]);
result.put("middle", res[1]);
result.put("line2", res[2]);
return result.toString();
} else {
this.data.log.info("Mainframe got a unknown command " + msg);
return "{\"command\":\"error\",\"reason\":\"unknown command\"}";
}
} catch (JSONException ex) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
ex.printStackTrace(new PrintStream(os));
data.log.severe("Got JSON Exception in run: " + os.toString());
return "{\"command\":\"error\",\"reason\":\"JSON format error\"}";
}
}
private String error(String message) {
return "{\"command\":\"error\",\"reason\":\"" + message + "\"}";
}
@Override
public boolean shouldClose() {
return _shouldClose;
}
}