/** * Persists shell state. If fails, calls {@link ru.fizteh.fivt.students.fedorov_andrew * .databaselibrary.shell.ShellState#prepareToExit(int)} with non zero exit code. */ private void persistSafelyAndPrepareToExit() throws ExitRequest { try { shellState.persist(); shellState.prepareToExit(0); } catch (ExitRequest request) { throw request; } catch (Exception exc) { Log.log(Shell.class, exc, "Failed to persist shell state"); shellState.prepareToExit(1); } }
/** Prepares shell for further command interpretation */ private void init() throws TerminalException { Log.log(Shell.class, "Shell starting"); try { shellState.init(this); } catch (Exception exc) { Utility.handleError(exc.getMessage(), exc, true); } commandMap = shellState.getCommands(); }
/** Execute commands from input stream. Commands are awaited till the-end-of-stream. */ public int run(InputStream stream) throws TerminalException { interactive = true; if (stream == null) { throw new IllegalArgumentException("Input stream must not be null"); } boolean exitRequested = false; try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream), READ_BUFFER_SIZE)) { while (true) { System.out.print(shellState.getGreetingString()); String str = reader.readLine(); // End of stream. if (str == null) { break; } List<String[]> commands = splitCommandsString(str); try { for (String[] command : commands) { execute(command); } } catch (TerminalException exc) { // Exception is already handled. } } } catch (IOException | ParseException exc) { exitRequested = true; Utility.handleError("Error in input stream: " + exc.getMessage(), exc, true); // No need to cleanup - work has not been started. } catch (ExitRequest request) { exitRequested = true; return request.getCode(); } finally { if (!exitRequested) { try { persistSafelyAndPrepareToExit(); } catch (ExitRequest request) { return request.getCode(); } } } // If all contracts are honoured, this line is unreachable. throw new AssertionError("No exit request performed"); }
/** * Execute commands from command line arguments. Note that command line arguments are first * concatenated into a single line then split and parsed. * * @param args Array of commands. If an error happens during execution of one of the commands in * the sequence, next commands will not be executed. * @return Exit code. 0 means normal status, anything else - abnormal termination (error). */ public int run(String[] args) throws TerminalException { try { interactive = false; try { List<String[]> commands = splitCommandsString(String.join(" ", args)); for (String[] command : commands) { execute(command); } } catch (TerminalException exc) { // Exception already handled. shellState.prepareToExit(1); } catch (ParseException exc) { Utility.handleError("Cannot parse command arguments: " + exc.getMessage(), exc, true); } persistSafelyAndPrepareToExit(); } catch (ExitRequest request) { return request.getCode(); } // If all contracts are honoured, this line is unreachable. throw new AssertionError("No exit request performed"); }