Archived
0

Zond: первые наметки коммандной оболочки

This commit is contained in:
2017-06-15 15:05:40 +03:00
parent 82fcdcdfe8
commit d8d80cf6dc
8 changed files with 221 additions and 30 deletions

View File

@@ -1,12 +1,25 @@
/*
* DmitriyMX <dimon550@gmail.com>
* 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();
}
}
}

View File

@@ -0,0 +1,9 @@
/*
* DmitriyMX <d.mihailov@samson-rus.com>
* 2017-06-15
*/
package asys.zond.shell;
public interface CommandHandler {
void handle(String commandLine);
}

View File

@@ -0,0 +1,35 @@
/*
* DmitriyMX <d.mihailov@samson-rus.com>
* 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);
}
}
}

View File

@@ -0,0 +1,12 @@
/*
* DmitriyMX <d.mihailov@samson-rus.com>
* 2017-06-15
*/
package asys.zond.shell;
public class EchoCommandHandler implements CommandHandler {
@Override
public void handle(String commandLine) {
Shell.getInstance().getOutput().println(commandLine);
}
}

View File

@@ -0,0 +1,62 @@
/*
* DmitriyMX <d.mihailov@samson-rus.com>
* 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);
}
}

View File

@@ -0,0 +1,9 @@
/*
* DmitriyMX <d.mihailov@samson-rus.com>
* 2017-06-15
*/
package asys.zond.shell;
public interface ShellOutputHook {
String handle(String line);
}

View File

@@ -0,0 +1,75 @@
/*
* DmitriyMX <d.mihailov@samson-rus.com>
* 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);
}
}