package mykeynote.server.nonpersistent;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import sun.util.logging.resources.logging;
import mykeynote.exceptions.keynote.RetValStringNotParsableException;
import mykeynote.exceptions.keynote.cl.KeyNoteCLException;
import mykeynote.exceptions.keynote.cl.KeyNoteCLProcessCreationException;
import mykeynote.keynote.KeyNoteCL;
import mykeynote.misc.FormatConstants;
import mykeynote.misc.ProtocolConstants;
import mykeynote.server.Main;
import mykeynote.server.Report;
import mykeynote.server.configuration.Configuration;
public class MyKeyNoteProtocol extends Thread{
private static final Date date = new Date();
//Global options
private static final String END = ProtocolConstants.END;
private static final String LET = ProtocolConstants.LET;
//Modes
private static final String interactivemode = ProtocolConstants.INTERACTIVEMODE;
private static final String fastmode = ProtocolConstants.FASTMODE;
//Environment strings
private static final String resource = ProtocolConstants.RESOURCE;
private static final String endResource = ProtocolConstants.ENDRESOURCE;
private static final String key = ProtocolConstants.KEY;
private static final String endKey = ProtocolConstants.ENDKEY;
private static final String cred = ProtocolConstants.CRED;
private static final String endCred = ProtocolConstants.ENDCRED;
private static final String env = ProtocolConstants.ENV;
private static final String endEnv = ProtocolConstants.ENDENV;
// Menus
private static final String fal = "false\nError while reading/writing";
private static final String help = "help";
private static final String helpMenu = "Allowed modes:\n\tfastmode\n\tcontinuous\t\nType <<<END>>> to quit";
private static final String currentVersion = "0.1";
private String resourceT;
private String clientVersion;
private BufferedReader in;
private PrintWriter out;
private String output;
private String input = "";
private String unique;
// private int credUn = 1; //Unique for cred
// private int envUn = 1; //Unique for env
private PrintWriter pr = null; //Used everywhere to print
private boolean withCred = true; //per default we have cred
// private static KeyNoteThread kn = Main.getKeyNoteThread();
private KeyNoteCL cl;
// report & Configuration
private static Report report;
private static Configuration config;
public MyKeyNoteProtocol(BufferedReader read, PrintWriter print, String client, Configuration config, Report report, String unique){
MyKeyNoteProtocol.config = config;
MyKeyNoteProtocol.report = report;
this.unique = unique;
in = read;
out = print;
cl = new KeyNoteCL(config, report);
}
public void run(){
// while(true) {
if(!Main.getStarted()){
out.println("Server down");
endit(false);
return;
} else {
if(!readLine()){
out.println(fal);
endit(false);
return;
}
//getting options and starting the needed mode
//report.reportVerbouseLog(unique, input);
if(input.compareTo(fastmode) == 0){
fastmode();
endit(false);
} else if (input.compareTo(interactivemode) == 0){
interactive();
} else {
out.println("false\nUnknown mode option: " + input);
endit(false);
return;
}
}
//}
}
private void fastmode(){
if(!config.increaseCurrentlyConnectedClients()){
report.reportServerLog("Maximum number of clients reached!");
return;
}
/* Using endit() + return the connection will be closed
* in case of errors/exceptions/mailfunction
*/
let();
if(!readLine()){
endit(false);
return;
}
//version
if(input.startsWith("version:")){
clientVersion = input.substring(8);
if(clientVersion.compareTo(currentVersion) != 0){
out.println("Server error: Unsupported client version, " +
"please use a version compliable with Server version" + currentVersion);
endit(false);
}
out.println("version:" + currentVersion);
out.flush();
if(!readLine()){
endit(false);
return;
}
}
File keyFile = null;
if(input.compareTo(key) == 0){
let();
keyFile = fastFile(endKey);
if(keyFile == null){
report.reportErrorLog(unique, "The key file could not created.");
endit(false);
return;
}
} else {
out.println("false\nClient error: Error while retreating key!");
endit(false);
return;
}
let();
if(!readLine()){
endit(false);
return;
}
File credFile = null;
if(input.compareTo(cred) == 0){
let();
credFile = fastFile(endCred);
if(credFile == null){
endit(false);
return;
}
} else {
out.println("false\nClient error: Error while retreating credential!");
endit(false);
return;
}
let();
if(!readLine()){
endit(false);
return;
}
File envFile = null;
if(input.compareTo(env) == 0){
let();
envFile = fastFile(endEnv);
if(envFile == null){
endit(false);
return;
}
} else {
out.println("false\nClient error: Error while retreating enviroment!");
endit(false);
return;
}
let();
if(!readLine()){
endit(false);
return;
}
if(input.compareTo(resource) == 0){
let();
if(!readLine()){
endit(false);
return;
}
resourceT = input;
let();
if(!readLine()){
endit(false);
return;
}
if(input.compareTo(endResource) != 0){
out.println("false\nOnly one line is allowed for resource");
endit(false);
return;
}
} else {
out.println("false\nThe forth option should be resource, check your client!");
endit(false);
return;
}
String ant = null;
try {
//ant = cl.verify(unique, report, new File(resourceT), keyFile);
ant = cl.verify(unique, report, envFile,credFile, keyFile, new File(resourceT));
//ant = kn.keynoteU(unique, resourceT, key, withCred);
//TODO get all exceptions by type
} catch (Exception e) {
report.reportErrorLog(unique, e.getMessage());
out.println("false\n...");
out.flush();
endit(false);
return;
}
let();
out.println(ant);
out.println(END);
out.flush();
return;
}
private void interactive(){
boolean goon = true;
while(goon){
if(input.compareTo(fastmode) == 0){
fastmode();
out.println("Back to main Menu!");
let();
} else if(input.compareTo(help) == 0){
out.println(helpMenu);
let();
} else if(input.compareTo(END) == 0){
out.println("Exiting!");
goon = false;
} else {
output = "Unknown option " + input + " For help please type " + help;
out.print(output);
let();
report.reportDebugLog(unique, "Unknown option " + input + " was given from the client.");
}
}
}
private File fastFile(String typeEnd){
if(!readLine())
return null;
String name = null;
if(typeEnd.compareTo(endCred) == 0){
name = new File(config.getTempDir(), unique + FormatConstants.CREDFORMAT).getAbsolutePath();
} else {
name = new File(config.getTempDir(), unique + "." + typeEnd.substring(2,5)).getAbsolutePath();
}
File file = new File(name);
if(file.exists()){
report.reportErrorLog(unique, "Trying to save temp file: " + name + ", but it already exists!");
out.println("false\nServer error: temp file exists!");
return null;
} else {
try{
file.createNewFile();
pr = new PrintWriter(file, "ASCII");
} catch (IOException e){
report.reportErrorLog(unique, "Server error: unable to create new temp file!");
out.println("false\nServer error: unable to create new temp file!");
return null;
}
}
if(input.compareTo(typeEnd) == 0){
if(input.compareTo(endCred) == 0)
withCred = false;
pr.close();
return file;
}
if(typeEnd.compareTo(endEnv) == 0){
pr.println("time=\"" + date.getTime()+"\"");
}
//Saving first line
pr.print(input);
let();
//no println, because we have to ensure that after the last line there will be no extra new line
while(true){
if(!readLine())
return null;
if(input.compareTo(typeEnd) !=0){
pr.println();
pr.print(input);
let();
} else{
pr.flush();
pr.close();
return file;
}
}
}
private boolean readLine(){
if(isInterrupted()){
out.println("false\nStopping server");
return false;
}
try{
input = in.readLine();
} catch (IOException e){
report.reportDebugLog(unique, "Unable to read a line!");
out.println(fal);
return false;
}
if(input == null){
report.reportDebugLog(unique, "Submitted a null value.");
return false;
}
report.reportDebugLog(unique, input);
if(input.compareTo(END) == 0)
return false;
return true;
}
private void let(){
report.reportDebugLog(unique, LET);
out.println(LET);
out.flush();
}
/**
* Ends a connection and frees all resources.
* @param persistent Returns <b>true,/b> if the connection is persistent,
* else returns <b>false</b>.
*/
private void endit(boolean persistent){
if(persistent){
config.decreaseCurrentlyConnectedPC();
} else {
config.decreaseCurrentlyConnectedClients(); //decreasing the active number of connections
}
out.println(END);
out.flush();
out.close();
try {
in.close();
} catch (IOException e) {
if(!config.getReportToConsole())
report.reportErrorLog(unique, "IO Exception hit in MyKeyNoteProtocol while closing the connection.");
return;
}
}
/*private boolean getCredentials(){
File file = new File(config.getTempDir(), unique + "_" + credUn + FormatConstants.CREDFORMAT);
String name = file.getAbsolutePath();
if(readLine()){
if(input.compareTo(cred) != 0)
return false;
if(file.exists()){
report.reportErrorLog(unique, "Trying to save temp file: " + name + ", but it already exists!");
out.println("false\nServer error: temp file exists!");
return false;
} else {
try{
file.createNewFile();
pr = new PrintWriter(file, "ASCII");
} catch (IOException e){
report.reportErrorLog("localhost", "Server error: unable to create new temp file!");
out.println("false\nServer error: unable to create new temp file!");
return false;
}
}
let();
if(!readLine()){
return false;
}
//first (and only) credential empty allowed
if(input.compareTo(endCred) == 0)
withCred = false;
pr.close();
if(!readLine()){
return false;
}
return true;
}
//getting the first credential
while(input.compareTo(endCred) != 0){
pr.write(input);
let();
if(!readLine()){
return false;
}
}
pr.close();
let();
if(!readLine()){
return false;
}
//checking for other creds
if(input.compareTo(cred) != 0)
return true;
//for all other creds
while(input.compareTo(cred) == 0){
let();
if(!readLine()){
return false;
}
if(input.compareTo(endCred) == 0){
out.println("false\nOnly the first Credential can be empty");
return false;
}
credUn++;
name = new File(config.getTempDir(), unique + "_" + credUn + FormatConstants.CREDFORMAT).getAbsolutePath();
createFile(name);
while(input.compareTo(endCred) != 0){
pr.write(input);
let();
if(!readLine()){
return false;
}
}
pr.flush();
pr.close();
if(!readLine()){
return false;
}
return true;
}
return false;
} */
/* private boolean getEnviroments(){
String name = new File(config.getTempDir(), unique + "_" + credUn + FormatConstants.CREDFORMAT).getAbsolutePath();
if(!createFile(name))
return false;
if(readLine()){
if(input.compareTo(env) != 0){
out.println("false\nCleint error: No enviroment given!");
return false;
}
let();
if(!readLine()){
return false;
}
//empty enviroment not allowed
if(input.compareTo(endEnv) == 0){
out.println("false\nClient error: Empty enviroment!");
out.flush();
pr.write("# Error, empty enviroment!");
pr.flush();
pr.close();
return false;
}
//getting the first enviroment
while(input.compareTo(endEnv) != 0){
pr.write(input);
let();
if(!readLine()){
return false;
}
pr.flush();
pr.close();
return true;
}
let();
if(!readLine()){
return false;
}
//getting all other envs
while(input.compareTo(env) == 0){
envUn++;
name = new File(config.getTempDir(), unique + "_" + credUn + FormatConstants.CREDFORMAT).getAbsolutePath();
if(!createFile(name))
return false;
let();
if(!readLine()){
return false;
}
if(input.compareTo(endEnv) == 0){
out.println("false\nClient error: empty enviroment!");
out.flush();
return false;
}
while(input.compareTo(endEnv) != 0){
pr.write(input);
let();
if(!readLine()){
return false;
}
}
let();
if(!readLine()){
return false;
}
pr.flush();
pr.close();
}
return true;
}
return false;
}
*/
/*
private boolean createFile(String name){
File file = new File(name);
if(file.exists()){
report.reportErrorLog(unique, "Trying to save temp file: " + name + ", but it already exists!");
out.println("false\nServer error: temp file exists!");
return false;
} else {
try{
file.createNewFile();
pr = new PrintWriter(file, "ASCII");
} catch (IOException e){
report.reportErrorLog("localhost", "Server error: unable to create new temp file!");
out.println("false\nServer error: unable to create new temp file!");
return false;
}
}
return true;
}
*/
}