package org.smartly.commons.cmdline; import org.smartly.commons.util.FormatUtils; import org.smartly.commons.util.StringUtils; import java.io.BufferedReader; import java.io.InputStreamReader; /** * Console Application */ public abstract class ConsoleApp { // -------------------------------------------------------------------- // c o n s t a n t s // -------------------------------------------------------------------- public static final String CMD_EXIT = "quit"; public static final String CMD_BACK = "back"; private static final String WELCOME = "**********************************************************\n" + "\t\t\t STARTED {0} CONSOLE\n" + "**********************************************************"; private static final String PAGE = "\t\t\t PAGE '{0}'\n" + "**********************************************************"; private static final String PRESS_ANY_KEY = "PRESS ANY KEY TO CONTINUE... "; private static final String CHOOSE_PAGE = "WRITE '" + CMD_BACK + "' TO GO BACK, '" + CMD_EXIT + "' TO EXIT OR CHOOSE A PAGE.\n" + "PAGE NAME: "; private static final String CHOOSE_COMMAND = "WRITE '" + CMD_BACK + "' TO GO BACK, '" + CMD_EXIT + "' TO EXIT OR CHOOSE A COMMAND.\n" + "COMMAND NAME:"; private static final String INVALID_PAGE = "INVALID PAGE NAME: '{0}'. PLEASE, CHOOSE A VALID PAGE NAME."; private static final String INVALID_COMMAND = "INVALID COMMAND NAME: '{0}'. PLEASE, CHOOSE A VALID COMMAND."; private static final String WAIT = "RUNNING COMMAND '{0}', PLEASE WAIT"; private static final String COMMAND_RESPONSE = "Command elapsed time {0} ms with response: {1}"; private static final String COMMAND_LIST = "COMMANDS:"; // -------------------------------------------------------------------- // f i e l d s // -------------------------------------------------------------------- private final String _name; private final ConsoleAppPages _pages; private BufferedReader _in; private ConsoleAppPage _curr_page; // -------------------------------------------------------------------- // c o n s t r u c t o r // -------------------------------------------------------------------- public ConsoleApp(final String name) { _name = name; _pages = new ConsoleAppPages(); this.initialize(_pages); _in = new BufferedReader(new InputStreamReader(System.in)); } // -------------------------------------------------------------------- // p u b l i c // -------------------------------------------------------------------- protected abstract void initialize(final ConsoleAppPages pages); /** * Start Console Application */ public void run() { this.println(FormatUtils.format(WELCOME, _name)); this.println(""); this.reset(); try { while (true) { final String key = read(); if(null==key){ break; } else if (!StringUtils.hasText(key)) { this.reset(); } else { if (key.equalsIgnoreCase(CMD_EXIT)) { break; } else if (key.equalsIgnoreCase(CMD_BACK)) { _curr_page = null; this.reset(); } else { // key is a command or a page name if (null != _curr_page) { // command this.runCommand(key); } else { this.gotoPage(key, _pages.getPage(key)); } } } } } catch (Throwable t) { t.printStackTrace(); } } // -------------------------------------------------------------------- // p r i v a t e // -------------------------------------------------------------------- private void reset() { if (_pages.count() == 1) { // single page gotoPage("", _pages.getDefault()); } else { // enum pages println(_pages.toString()); } } private void println(final String output) { System.out.println(output); } private String read() { try { return _in.readLine(); } catch (Throwable ignored) { return null; } } private void gotoPage(final String key, final ConsoleAppPage page) { if (null != page) { _curr_page = page; if (StringUtils.hasText(key)) { this.println(FormatUtils.format(PAGE, page.getName())); } this.println(COMMAND_LIST); this.println(""); this.println(_curr_page.enumCommands()); this.println(""); this.println(CHOOSE_COMMAND); } else { this.println(FormatUtils.format(INVALID_PAGE, key)); this.println(CHOOSE_PAGE); } } private void runCommand(final String key) { if (null != _curr_page) { if (_curr_page.hasCommand(key)) { // start command final long start = System.currentTimeMillis(); final ConsoleAppTicker ticker = new ConsoleAppTicker(); this.println(FormatUtils.format(WAIT, key)); ticker.start(); final Object response = _curr_page.runCommand(key); // command finished final long finish = System.currentTimeMillis(); ticker.interrupt(); // write response this.println(FormatUtils.format(COMMAND_RESPONSE, finish - start, response)); this.println(PRESS_ANY_KEY); } else { this.println(FormatUtils.format(INVALID_COMMAND, key)); this.println(CHOOSE_COMMAND); } } else { // invalid status. reset this.reset(); } } // -------------------------------------------------------------------- // EMBEDDED // -------------------------------------------------------------------- private class ConsoleAppTicker extends Thread { @Override public synchronized void run() { try { while (!this.isInterrupted()) { Thread.sleep(500); System.out.print("."); } } catch (Throwable ignored) { } } } }