package se.chalmers.gdcn.ui;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import se.chalmers.gdcn.communicationToUI.*;
import se.chalmers.gdcn.control.PeerOwner;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* Created by HalfLeif on 2014-02-19
*/
public class Console implements PropertyChangeListener{
/**
* Starts a client, adding a console to it and starts reading commands from CLI.
* <p>-nosplash option disables the splash screen on start</p>
* @param args console arguments
*/
public static void main(String[] args){
List<String> arguments = Arrays.asList(args);
if (!arguments.contains("-nosplash"))
SplashScreen.print();
Logger.getRootLogger().setLevel(Level.WARN);
ClientInterface client = new PeerOwner();
Console console = ConsoleFactory.create(client);
console.read();
}
private final int HELP_INLINE = 24;
private final Holder commandHolder;
private boolean loop = true;
/**
* Package-private constructor used by {@link se.chalmers.gdcn.ui.ConsoleFactory#create(se.chalmers.gdcn.communicationToUI.ClientInterface)}.
* @param commandMap map of possible client commands
*/
Console(Map<String, UICommand> commandMap) {
commandMap.put(MetaCommand.EXIT.getName(), new UICommand() {
@Override
public void execute(List<String> args) {
loop = false;
}
@Override
public WordInterface getWord() {
return MetaCommand.EXIT;
}
});
commandMap.put(MetaCommand.HELP.getName(), new UICommand() {
@Override
public void execute(List<String> args) {
//TODO use TreeSet instead for alphabetical order?
List<WordInterface> words = new ArrayList<>();
words.addAll(Arrays.asList(CommandWord.values()));
words.addAll(Arrays.asList(MetaCommand.values()));
println("-- Commandname (arguments): description --");
for(WordInterface word : words){
String init = word.getName() + " " + word.getArguments();
int whitespaces = HELP_INLINE - init.length();
println(init + StringUtils.repeat(" ", whitespaces) + word.getHelp());
println("");
}
println("");
}
@Override
public WordInterface getWord() {
return MetaCommand.HELP;
}
});
commandMap.put(MetaCommand.ABOUT.getName(), new UICommand() {
@Override
public void execute(List<String> args) {
println("GDCN - General Decentralized Computation Network\n");
println("Developed in 2014 by\n" +
"\tJack Pettersson\n" +
"\tLeif Schelin\n" +
"\tNiklas Wärvik\n" +
"\tJoakim Öhman\n");
println("@Chalmers University of Technology");
println("Latest version can be found on\n" +
"\thttps://github.com/GDCN/GDCN");
}
@Override
public WordInterface getWord() {
return MetaCommand.ABOUT;
}
});
this.commandHolder = new Holder(commandMap);
}
/**
* Receives results from the Client on various operations.
* @param evt event
*/
@Override
public void propertyChange(PropertyChangeEvent evt) {
OperationFinishedEvent event = (OperationFinishedEvent) evt;
String success = event.getOperation().isSuccess()? "succeeded" : "failed";
switch(event.getCommandWord()){
case BOOTSTRAP:
println("Bootstrap " + success);
break;
case WORK:
println("Work on " + event.getOperation().getKey() + " " + success);
break;
case AUTO_WORK:
println("Autowork on " + event.getOperation().getKey() + " " + success);
break;
case PUSH:
println("Push job " + event.getOperation().getKey() + " " + success);
break;
case STOP:
break;
case PUT:
//Disabled for demo
//println("Put " + event.getOperation().getKey() + " " + success);
break;
case GET:
//Disabled for demo
//println("Got " + event.getOperation().getKey() + " " + success);
break;
case START:
print("Start complete");
String address = event.getOperation().getResult().toString();
if(address != null){
println(": "+address);
} else {
println(".");
}
break;
case INSTALL:
println("Installation complete.");
break;
case UNINSTALL:
println("Uninstallation complete.");
break;
default:
println("Console: Returned cmd with unimplemented output: " + event.getCommandWord().getName());
break;
}
String reason = event.getOperation().getReason();
if(reason!=null){
println(reason);
}
}
/**
* Prints message + newline, exchangeable
* @param message String to print
*/
private void println(String message){
System.out.println(message);
}
/**
* Prints message, exchangeable
* @param message String to print
*/
private void print(String message){
System.out.print(message);
}
/**
* Loop for reading commands from CLI
*/
public void read(){
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
try {
while(loop){
print("\n>> ");
String line = bufferedReader.readLine();
String[] words = line.split("\\s");
List<String> wordList = new ArrayList<>(Arrays.asList(words));
String cmd = wordList.remove(0);
if("".equals(cmd)){
continue;
}
boolean exception = true;
try{
commandHolder.execute(cmd, wordList);
exception = false;
} catch (UnsupportedOperationException e){
println("Unsupported operation (\"" + cmd + "\").");
} catch (NumberFormatException e){
println("Expected a number here.");
} catch (Exception e){
println("Unexpected exception!");
println(e.getMessage());
} finally {
if(exception){
println("Type \"help\" to see a list of commands. Type \"exit\" to stop.");
}
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}