From d8d80cf6dc4f9395f916178ee8c62d4db7bce55a Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Thu, 15 Jun 2017 15:05:40 +0300 Subject: [PATCH] =?UTF-8?q?Zond:=20=D0=BF=D0=B5=D1=80=D0=B2=D1=8B=D0=B5=20?= =?UTF-8?q?=D0=BD=D0=B0=D0=BC=D0=B5=D1=82=D0=BA=D0=B8=20=D0=BA=D0=BE=D0=BC?= =?UTF-8?q?=D0=BC=D0=B0=D0=BD=D0=B4=D0=BD=D0=BE=D0=B9=20=D0=BE=D0=B1=D0=BE?= =?UTF-8?q?=D0=BB=D0=BE=D1=87=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- zond/build.gradle | 28 +------ zond/src/main/java/asys/zond/Main.java | 21 +++++- .../java/asys/zond/shell/CommandHandler.java | 9 +++ .../java/asys/zond/shell/CommandLooper.java | 35 +++++++++ .../asys/zond/shell/EchoCommandHandler.java | 12 +++ zond/src/main/java/asys/zond/shell/Shell.java | 62 +++++++++++++++ .../java/asys/zond/shell/ShellOutputHook.java | 9 +++ .../java/asys/zond/shell/ShellStdOut.java | 75 +++++++++++++++++++ 8 files changed, 221 insertions(+), 30 deletions(-) create mode 100644 zond/src/main/java/asys/zond/shell/CommandHandler.java create mode 100644 zond/src/main/java/asys/zond/shell/CommandLooper.java create mode 100644 zond/src/main/java/asys/zond/shell/EchoCommandHandler.java create mode 100644 zond/src/main/java/asys/zond/shell/Shell.java create mode 100644 zond/src/main/java/asys/zond/shell/ShellOutputHook.java create mode 100644 zond/src/main/java/asys/zond/shell/ShellStdOut.java diff --git a/zond/build.gradle b/zond/build.gradle index 887f6d1..bba81ae 100644 --- a/zond/build.gradle +++ b/zond/build.gradle @@ -1,5 +1,5 @@ group = 'asys' -version = '0.6.1-SNAPSHOT' +version = '0.7.1-SNAPSHOT' apply plugin: 'application' @@ -7,25 +7,11 @@ mainClassName = "asys.zond.Main" configurations { included - includedEx compile.extendsFrom included - compile.extendsFrom includedEx -} - -compileJava { - dependsOn ':bridge-protocol:compileJava' -} - -def zp(FileTree ft) { - return ft.matching { - exclude 'org/apache/commons/exec/StreamPumper.class' - } } jar { - dependsOn ':bridge-protocol:jar' dependsOn configurations.included - dependsOn configurations.includedEx manifest { attributes 'Implementation-Title': 'ASys Zond', 'Implementation-Version': version, @@ -33,18 +19,8 @@ jar { } baseName = project.group + '.' + project.name from { configurations.included.collect { it.isDirectory() ? it : zipTree(it) } } - from { configurations.includedEx.collect { it.isDirectory() ? it : zp(zipTree(it)) } } -} - -ext { - nettyVersion = '4.0.23.Final' } dependencies { - included files(project(':bridge-protocol').sourceSets.main.output.classesDir) - included group: 'org.fusesource.jansi', name: 'jansi', version: '1.11' - includedEx group: 'org.apache.commons', name: 'commons-exec', version: '1.3' - included group: 'io.netty', name: 'netty-codec', version: nettyVersion - included group: 'com.google.guava', name: 'guava', version: '21.0' - included group: 'jline', name: 'jline', version: '2.13' + included group: 'jline', name: 'jline', version: '2.14.3' } diff --git a/zond/src/main/java/asys/zond/Main.java b/zond/src/main/java/asys/zond/Main.java index e73e088..37621ba 100644 --- a/zond/src/main/java/asys/zond/Main.java +++ b/zond/src/main/java/asys/zond/Main.java @@ -1,12 +1,25 @@ /* * DmitriyMX - * 2017-06-07 + * 2017-06-15 * Idea by Daniil on 2017-06-07 */ package asys.zond; -public class Main { - public static void main(String[] args) { +import asys.zond.shell.Shell; +import java.io.IOException; + +public class Main { + public static void main(String[] args) throws IOException { + new Main().start(); } -} + + private void start() { + Shell shell = Shell.getInstance(); + try { + shell.start(System.in); + } catch (Exception e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/zond/src/main/java/asys/zond/shell/CommandHandler.java b/zond/src/main/java/asys/zond/shell/CommandHandler.java new file mode 100644 index 0000000..197ead7 --- /dev/null +++ b/zond/src/main/java/asys/zond/shell/CommandHandler.java @@ -0,0 +1,9 @@ +/* + * DmitriyMX + * 2017-06-15 + */ +package asys.zond.shell; + +public interface CommandHandler { + void handle(String commandLine); +} diff --git a/zond/src/main/java/asys/zond/shell/CommandLooper.java b/zond/src/main/java/asys/zond/shell/CommandLooper.java new file mode 100644 index 0000000..0460312 --- /dev/null +++ b/zond/src/main/java/asys/zond/shell/CommandLooper.java @@ -0,0 +1,35 @@ +/* + * DmitriyMX + * 2017-06-15 + */ +package asys.zond.shell; + +import jline.console.ConsoleReader; + +import java.io.IOException; + +public class CommandLooper implements Runnable { + private ConsoleReader consoleReader; + private CommandHandler commandHandler; + + CommandLooper(ConsoleReader consoleReader, CommandHandler commandHandler) { + this.consoleReader = consoleReader; + this.commandHandler = commandHandler; + } + + @Override + public void run() { + while (!Thread.currentThread().isInterrupted()) { + String line; + try { + line = consoleReader.readLine(); + } catch (IOException e) { + break; + } + if (line == null) break; + if (line.trim().isEmpty()) continue; + + commandHandler.handle(line); + } + } +} diff --git a/zond/src/main/java/asys/zond/shell/EchoCommandHandler.java b/zond/src/main/java/asys/zond/shell/EchoCommandHandler.java new file mode 100644 index 0000000..fa3741c --- /dev/null +++ b/zond/src/main/java/asys/zond/shell/EchoCommandHandler.java @@ -0,0 +1,12 @@ +/* + * DmitriyMX + * 2017-06-15 + */ +package asys.zond.shell; + +public class EchoCommandHandler implements CommandHandler { + @Override + public void handle(String commandLine) { + Shell.getInstance().getOutput().println(commandLine); + } +} diff --git a/zond/src/main/java/asys/zond/shell/Shell.java b/zond/src/main/java/asys/zond/shell/Shell.java new file mode 100644 index 0000000..13b914e --- /dev/null +++ b/zond/src/main/java/asys/zond/shell/Shell.java @@ -0,0 +1,62 @@ +/* + * DmitriyMX + * 2017-06-15 + */ +package asys.zond.shell; + +import jline.console.ConsoleReader; + +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintStream; + +public class Shell { + private static final String DEFAULT_PROMPT = ":"; + private static Shell instance; + private ConsoleReader consoleReader; + private Thread threadCommandLoop; + private CommandHandler commandHandler; + private ShellStdOut shellStdOut; + + public static Shell getInstance() { + if (instance == null) instance = new Shell(); + return instance; + } + + private Shell() { + } + + public void start(InputStream inputStream) throws IOException { + consoleReader = new ConsoleReader(inputStream, (shellStdOut = new ShellStdOut())); + shellStdOut.setConsoleReader(consoleReader); + consoleReader.setPrompt(DEFAULT_PROMPT); + + if (commandHandler == null) commandHandler = new EchoCommandHandler(); + + threadCommandLoop = new Thread( + new CommandLooper(consoleReader, commandHandler), + "Zond shell looper"); + threadCommandLoop.start(); + } + + public void shutdown() { + threadCommandLoop.interrupt(); + consoleReader.close(); + } + + public void setPrompt(String value) { + consoleReader.setPrompt(value); + } + + public void resetPrompt() { + consoleReader.setPrompt(DEFAULT_PROMPT); + } + + public PrintStream getOutput() { + return shellStdOut; + } + + public void setOutputHook(ShellOutputHook outputHook) { + shellStdOut.setOutputHook(outputHook); + } +} diff --git a/zond/src/main/java/asys/zond/shell/ShellOutputHook.java b/zond/src/main/java/asys/zond/shell/ShellOutputHook.java new file mode 100644 index 0000000..9936e2e --- /dev/null +++ b/zond/src/main/java/asys/zond/shell/ShellOutputHook.java @@ -0,0 +1,9 @@ +/* + * DmitriyMX + * 2017-06-15 + */ +package asys.zond.shell; + +public interface ShellOutputHook { + String handle(String line); +} diff --git a/zond/src/main/java/asys/zond/shell/ShellStdOut.java b/zond/src/main/java/asys/zond/shell/ShellStdOut.java new file mode 100644 index 0000000..6eac1c3 --- /dev/null +++ b/zond/src/main/java/asys/zond/shell/ShellStdOut.java @@ -0,0 +1,75 @@ +/* + * DmitriyMX + * 2017-06-15 + */ +package asys.zond.shell; + +import jline.console.ConsoleReader; + +import java.io.PrintStream; +import java.io.PrintWriter; + +public class ShellStdOut extends PrintStream { + private ConsoleReader consoleReader; + private PrintWriter writer; + private ShellOutputHook shellOutputHook; + + ShellStdOut() { + super(System.out, true); + } + + void setConsoleReader(ConsoleReader consoleReader) { + this.consoleReader = consoleReader; + this.writer = new PrintWriter(consoleReader.getOutput()); + } + + private void _print(String line) { + String newLine; + if (shellOutputHook != null) { + try { + newLine = shellOutputHook.handle(line); + if (newLine == null) return; + else line = newLine; + } catch (Exception ignore) { + } + } + + writer.print(ConsoleReader.RESET_LINE); + writer.print(line); + cleanTrashLine(line); + writer.println(); + writer.flush(); + } + + /** + * Очистка печатной строки от мусора + */ + private void cleanTrashLine(String string) { + // очищает полностью строку + if (consoleReader.getCursorBuffer().buffer.length() + consoleReader.getPrompt().length() > string.length()) { + for (int i = string.length(); i <= consoleReader.getCursorBuffer().buffer.length() + 2; i++) { + writer.print(' '); + } + } + } + + void setOutputHook(ShellOutputHook shellOutputHook) { + this.shellOutputHook = shellOutputHook; + } + + @Override + public void write(byte[] buf, int off, int len) { + if ((char)buf[len-1] == '\n') len--; + _print(new String(buf, off, len)); + } + + @Override + public void print(String s) { + _print(s); + } + + @Override + public void println(String x) { + _print(x); + } +}