import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.io.InputStreamReader; import java.util.HashMap; public class RandomShell implements Runnable { protected transient HashMap rnds; protected BufferedReader reader; protected PrintWriter writer; protected InputStream in; protected OutputStream out; protected ExitFunction exitFunc; public RandomShell() { rnds = new HashMap(); reader = null; } public void setInputStream(InputStream in) { this.in = in; reader = new BufferedReader(new InputStreamReader(this.in)); } public void setOutputStream(OutputStream out) { this.out = out; writer = new PrintWriter(out); } public void setExitFunction(ExitFunction efunc) { this.exitFunc = efunc; } public boolean ExecCmd(String cmd) { String[] splitedCmd = cmd.split(" "); switch(splitedCmd[0]) { case "exit": if(splitedCmd.length > 1) { try { this.exitFunc.exit(Integer.parseInt(splitedCmd[1])); } catch (NumberFormatException e) { writer.println("The exit code could not be parsed: " + e.getMessage()); return false; } } else { this.exitFunc.exit(0); } break; case "new": if(splitedCmd.length < 3) { writer.println("The command was not used correctly: new [CLASS] [NAME]"); writer.println("Example: new generator generator"); return false; } else { switch(splitedCmd[1]) { case "generator": case "g": rnds.put(splitedCmd[2], new RandomWrapper()); break; default: writer.println("The specified class could not be found."); return false; } } break; case "generate": if(splitedCmd.length < 2) { writer.println("The command was not used correctly: generate [GENERATOR]"); return false; } else if(! rnds.containsKey(splitedCmd[1])) { writer.println("The name of the generator was not found."); return false; } else { rnds.get(splitedCmd[1]).generate(); } break; case "next": if(splitedCmd.length < 2) { writer.println("The command was not used correctly: next [GENERATOR]"); return false; } else if(! rnds.containsKey(splitedCmd[1])) { writer.println("The random integer generator was not found."); return false; } else { try { writer.println(rnds.get(splitedCmd[1]).next()); } catch (NoRandomIntegerGenerated e) { writer.println("No random integer was previously generated: " + e.getMessage()); return false; } } break; case "reshape": if(splitedCmd.length < 4) { writer.println("The command was not used correctly: reshape [ID] [FROM] [TO]"); return false; } else if(! rnds.containsKey(splitedCmd[1])) { writer.println("The random integer generator was not found."); return false; } else { try { int from = Integer.parseInt(splitedCmd[2]); int to = Integer.parseInt(splitedCmd[3]) + 1; int num = Math.abs(rnds.get(splitedCmd[1]).next()); writer.println(num % (to - from) + from); } catch (NoRandomIntegerGenerated e) { writer.println("No random integer was previously generated: " + e.getMessage()); return false; } catch (NumberFormatException e) { writer.println("No random integer was previously generated: " + e.getMessage()); return false; } } break; case "loop": try { int cnt = Integer.parseInt(splitedCmd[1]); int beg = cmd.indexOf(' ', cmd.indexOf(' ') + 1) + 1; if(beg == -1 || beg == 0) { writer.println("The command was not used correctly: loop [COUNT] [COMMAND]"); return false; } for(int i = 0; i < cnt; i++) { if(! ExecCmd(cmd.substring(beg))) break; } } catch (NumberFormatException e) { writer.println("The number could not be parsed: " + e.getMessage()); return false; } break; case "echo": writer.println(cmd.substring(cmd.indexOf(' ') + 1)); break; default: writer.println("The specified command could not be found."); return false; } return true; } @Override public void run() { while(true) { this.writer.print("> "); this.writer.flush(); try { String readedCmd = this.reader.readLine().trim(); ExecCmd(readedCmd); } catch (IOException e) { this.writer.println("Error: Couldn't read the command."); this.writer.println(e.getMessage()); } } } public static void main(String[] args) { RandomShell shell = new RandomShell(); shell.setInputStream(System.in); shell.setOutputStream(System.out); shell.setExitFunction((code) -> { System.exit(code); }); Thread tr = new Thread(shell); tr.start(); try { tr.join(); } catch (InterruptedException e) { System.out.println("Interrupted: " + e.getMessage()); } } }