
org.structr.files.ssh.AbstractTerminalEmulator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of structr-ui Show documentation
Show all versions of structr-ui Show documentation
Structr is an open source framework based on the popular Neo4j graph database.
The newest version!
/**
* Copyright (C) 2010-2016 Structr GmbH
*
* This file is part of Structr .
*
* Structr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* Structr is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Structr. If not, see .
*/
package org.structr.files.ssh;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
*
*/
public abstract class AbstractTerminalEmulator extends Thread implements TerminalEmulator {
private static final Logger logger = Logger.getLogger(AbstractTerminalEmulator.class.getName());
protected final StringBuilder lineBuffer = new StringBuilder();
protected TerminalHandler rootTerminalHandler = null;
protected TerminalHandler terminalHandler = null;
protected Reader reader = null;
protected Writer writer = null;
protected boolean running = false;
protected boolean echo = true;
protected int cursorPosition = 0;
protected int lineLength = 0;
protected int commandBufferIndex = 0;
protected int tabCount = 0;
public AbstractTerminalEmulator(final InputStream in, final OutputStream out, final TerminalHandler rootTerminalHandler) {
this.rootTerminalHandler = rootTerminalHandler;
this.terminalHandler = rootTerminalHandler;
this.reader = new InputStreamReader(in);
this.writer = new OutputStreamWriter(out);
}
@Override
public void stopEmulator() {
this.running = false;
}
@Override
public void setTerminalHandler(final TerminalHandler handler) throws IOException {
this.terminalHandler = handler;
}
@Override
public void restoreRootTerminalHandler() throws IOException {
this.terminalHandler = rootTerminalHandler;
setEcho(true);
}
@Override
public void handleCursorUp() throws IOException {
final List commandHistory = terminalHandler.getCommandHistory();
if (commandHistory != null && echo) {
final int commandBufferSize = commandHistory.size();
if (commandBufferIndex >= 0 && commandBufferIndex < commandBufferSize) {
displaySelectedCommand(commandHistory.get(commandBufferSize - commandBufferIndex - 1));
if (commandBufferIndex < commandBufferSize - 1) {
commandBufferIndex++;
}
}
}
}
@Override
public void handleCursorDown() throws IOException {
final List commandHistory = terminalHandler.getCommandHistory();
if (commandHistory != null && echo) {
if (commandBufferIndex > 0) {
final int commandBufferSize = commandHistory.size();
if (commandBufferIndex >= 0 && commandBufferIndex <= commandBufferSize) {
commandBufferIndex--;
displaySelectedCommand(commandHistory.get(commandBufferSize - commandBufferIndex - 1));
}
} else {
displaySelectedCommand("");
}
}
}
@Override
public void handleCtrlKey(final int key) throws IOException {
// 0 is Ctrl-A, 1 is Ctrl-B, etc..
switch (key) {
case 3:
terminalHandler.handleCtrlC();
break;
case 4:
if (lineLength == 0) {
terminalHandler.handleLogoutRequest();
}
break;
}
}
@Override
public void run() {
running = true;
while (running) {
try {
int c = reader.read();
// global tab count
if (c == 9) {
tabCount++;
} else {
tabCount = 0;
}
switch (c) {
case 9:
handleTab(tabCount);
break;
case 13:
handleNewline();
break;
case 27:
// escape sequence
c = reader.read();
switch (c) {
case 91:
// cursor keys
c = reader.read();
switch (c) {
case 50:
// insert
c = reader.read();
switch (c) {
case 126:
handleInsert();
break;
}
break;
case 51:
// delete
c = reader.read();
switch (c) {
case 126:
handleDelete();
break;
}
break;
case 53:
// page up
c = reader.read();
switch (c) {
case 126:
handlePageUp();
break;
}
break;
case 54:
// page down
c = reader.read();
switch (c) {
case 126:
handlePageDown();
break;
}
break;
case 65:
// up
handleCursorUp();
break;
case 66:
// down
handleCursorDown();
break;
case 67:
handleCursorRight();
break;
case 68:
handleCursorLeft();
break;
case 70:
handleEnd();
break;
case 72:
handleHome();
break;
}
break;
}
break;
case 127:
handleBackspace();
break;
default:
if (c < 27) {
handleCtrlKey(c);
} else {
// read unicode character
handleCharacter(c);
}
break;
}
writer.flush();
} catch (Throwable t) {
logger.log(Level.WARNING, "", t);
if (writer != null) {
try {
writer.write('\n');
writer.write(t.getMessage());
writer.write('\n');
} catch (Throwable t2) {
logger.log(Level.WARNING, "", t);
}
}
}
}
terminalHandler.handleExit();
}
@Override
public void print(final String text) throws IOException {
writer.write(text);
writer.flush();
}
@Override
public void println(final String text) throws IOException {
writer.write(text);
println();
writer.flush();
}
@Override
public void clearLineBuffer() {
lineBuffer.setLength(0);
cursorPosition = 0;
lineLength = 0;
}
@Override
public StringBuilder getLineBuffer() {
return lineBuffer;
}
@Override
public void setEcho(final boolean echo) {
this.echo = echo;
}
@Override
public void flush() throws IOException {
writer.flush();
}
// ----- protected methods -----
protected void handleLineInternal(final String line) throws IOException {
terminalHandler.handleLine(line);
commandBufferIndex = 0;
}
// ----- private methods -----
private void displaySelectedCommand(final String selectedCommand) throws IOException {
lineBuffer.setLength(0);
lineBuffer.append(selectedCommand);
lineLength = lineBuffer.length();
int loopCount = cursorPosition;
for (int i=0; i
© 2015 - 2025 Weber Informatics LLC | Privacy Policy