/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.core.embedded.ssh.internal; import java.util.ArrayList; import java.util.List; /** * Class used to handle all possibilities of chars and char sequences. Provides a robust way of generating an command for the SSH console. * * @author Sebastian Holtappels * @author Robert Mischke */ public class InteractiveShellHandler { private StringBuffer commandBuffer; private StringBuffer preBuffer; private List<String> oldCommands; private int pointerForOldCmds; private int pointerForCmdBuffer; private SshConsoleOutputAdapter sshConsoleHandler; // private final Log log = LogFactory.getLog(getClass()); public InteractiveShellHandler(SshConsoleOutputAdapter sshConsoleHandler) { fullReset(); this.sshConsoleHandler = sshConsoleHandler; } /** * * Adds a new Char to this command. Due to specific processing the char might not be included in the comment (depending of its direct * context) * * @param newCharCode - the code of the new char to be added. (use (int) charToAdd)). * * @return true, if it should be printed to the console */ public boolean processInputChar(int newCharCode) { boolean doPrint = false; int charCode = preProcessSpecialKeys(newCharCode); if (charCode >= SshConstants.LOWEST_USEFUL_KEY_CODE || charCode == SshConstants.TAB_KEY_CODE) { char newChar = (char) charCode; if (charCode == SshConstants.DEL_KEY_CODE) { if (pointerForCmdBuffer > 0) { if (pointerForCmdBuffer < commandBuffer.length()) { printToConsole(commandBuffer.substring(pointerForCmdBuffer + 1)); } commandBuffer.deleteCharAt(pointerForCmdBuffer - 1); pointerForCmdBuffer--; doPrint = true; } else { doPrint = false; } } else { // add whatever it is, when it managed to reach this point. if (pointerForCmdBuffer == commandBuffer.length()) { commandBuffer.append(newChar); } else { commandBuffer.insert(pointerForCmdBuffer, newChar); } pointerForCmdBuffer++; doPrint = true; } } return doPrint; } private int preProcessSpecialKeys(int newCharCode) { int result = newCharCode; String temp = null; if (newCharCode == SshConstants.ESC_KEY_CODE) { // ESC_KEY_CODE is for a new special key (in all situations) . preBuffer = new StringBuffer(); result = SshConstants.NO_ADDING_INT_CODE; } else if (preBuffer != null && newCharCode != SshConstants.DEL_KEY_CODE) { // add whatever it is, when it managed to reach this point. preBuffer.append((char) newCharCode); temp = preBuffer.toString(); if (temp.matches(SshConstants.SPECIAL_KEY_REGEX)) { result = SshConstants.NO_ADDING_INT_CODE; handleKnownCodes(temp); } else { // not a valid value. add current value to command buffer and console preBuffer = null; } } return result; } private void handleKnownCodes(String subject) { if (subject.matches(SshConstants.SPECIAL_KEY_LEFT)) { // Disabled because it causes incorrect behavior. // if (pointerForCmdBuffer > 0) { // pointerForCmdBuffer--; // printToConsole((char) SshConstants.ESC_KEY_CODE + subject); // } preBuffer = null; } else if (subject.matches(SshConstants.SPECIAL_KEY_RIGHT)) { // Disabled because it causes incorrect behavior. // if (pointerForCmdBuffer < commandBuffer.length()) { // pointerForCmdBuffer++; // printToConsole((char) SshConstants.ESC_KEY_CODE + subject); // } preBuffer = null; } else if (subject.matches(SshConstants.SPECIAL_KEY_ENTF)) { if (pointerForCmdBuffer < commandBuffer.length() - 1) { commandBuffer.deleteCharAt(pointerForCmdBuffer + 1); printToConsole((char) SshConstants.ESC_KEY_CODE + subject); } preBuffer = null; } else if (subject.matches(SshConstants.SPECIAL_KEY_UP)) { if (pointerForOldCmds > 0) { pointerForOldCmds--; scrollThroughHistory(oldCommands.get(pointerForOldCmds)); } preBuffer = null; } else if (subject.matches(SshConstants.SPECIAL_KEY_DOWN)) { if (pointerForOldCmds < oldCommands.size()) { pointerForOldCmds++; if (pointerForOldCmds == oldCommands.size()) { scrollThroughHistory(""); } else { scrollThroughHistory(oldCommands.get(pointerForOldCmds)); } } } else if (subject.matches(SshConstants.SPECIAL_KEYS_IGNORE_LIST)) { // ignore these keys preBuffer = null; } } /** * * Returns the command and resets this instance so a new command can be created. * * @return the command as string. */ public String getCurrentCommand() { String command = commandBuffer.toString(); addToCommandHistory(command); reset(); return command; } /** * * Adds a command to the history List (oldCommands). Enables the use of key up and key down. * * @param command - the command to be added. */ public void addToCommandHistory(String command) { oldCommands.add(command); if (oldCommands.size() > SshConstants.COMMAND_HISTORY_SIZE) { oldCommands.remove(0); } else { pointerForOldCmds = oldCommands.size(); } } private void scrollThroughHistory(String newCommand) { char delete = (char) SshConstants.DEL_KEY_CODE; String deleteString = ""; for (int i = 0; i < commandBuffer.length(); i++) { deleteString = deleteString + delete; } reset(); commandBuffer.append(newCommand); pointerForCmdBuffer = commandBuffer.length(); printToConsole(deleteString + newCommand); } private void fullReset() { oldCommands = new ArrayList<String>(); pointerForOldCmds = 0; reset(); } private void reset() { commandBuffer = new StringBuffer(); preBuffer = null; pointerForCmdBuffer = 0; } private void printToConsole(String string) { sshConsoleHandler.addOutput(string, false, false); } }