package org.opennaas.extensions.protocols.cli; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Enumeration; import java.util.Hashtable; import java.util.List; import org.opennaas.extensions.protocols.cli.message.CLIResponseMessage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * * @author edu * */ public class CLIStreamReader { /** Logger */ static private Logger logger = LoggerFactory.getLogger(CLIStreamReader.class); /** The prompts used to detect the end of the message **/ private List<String> prompts; /** * Contains a pair of <intermediate_prompt, string to be send>, to make the remote agent continue sending the response message **/ private Hashtable<String, String> intermediatePrompts; /** Contains some of the strings that appear when the response message is an error message **/ private List<String> errorMessagePatterns; /** The stream to receive characters of the CLI response message **/ private BufferedReader cliStream; /** Int value for Carriage Return */ public static final int CR = 13; /** Int value for Line Feed */ public static final int LF = 10; /** Int value for valid character start */ public static final int VALIDSTART = 31; /** Int value for valid character stop */ public static final int VALIDSTOP = 127; /** String Buffer to input Data */ private StringBuilder buffer = null; /** PrintWriter to write to the stream transport */ private PrintWriter outPrint; /** * Creates a CLIStreamReader that will listen for the characters received in the stream, assemble response messages and parse them * * @param stream * @param oStream * @param prompts * @param intermediatePrompts * @param errorMessagePatterns */ public CLIStreamReader(InputStream stream, OutputStream oStream, List<String> prompts, Hashtable<String, String> intermediatePrompts, List<String> errorMessagePatterns) { this.prompts = prompts; this.intermediatePrompts = intermediatePrompts; this.errorMessagePatterns = errorMessagePatterns; cliStream = new BufferedReader(new InputStreamReader(stream)); outPrint = new PrintWriter(oStream, true); buffer = new StringBuilder(); } /** * Gets a response message from the input stream. If the request message is echoed, it will eliminate it from the response * * @param request * @return */ public CLIResponseMessage getResponse(String request) throws IOException { try { int c; String currentResponse = null; List<String> stringsToRemove = new ArrayList<String>(); stringsToRemove.add(request); CLIResponseMessage response = null; boolean end = false; while (((c = cliStream.read()) != -1) && !end) { if ((c > VALIDSTART && c < VALIDSTOP) || c == LF || c == CR) { // Append the character to the buffer of received characters buffer.append((char) c); currentResponse = buffer.toString(); // Check for prompts for (int i = 0; i < prompts.size(); i++) { if (currentResponse.indexOf(prompts.get(i)) != -1) { // Prompt detected, end of the message, parse it! logger.debug("Message received, let's process it: " + currentResponse); stringsToRemove.add(prompts.get(i)); // process message response = CLIResponseMessage.parse(currentResponse, stringsToRemove, errorMessagePatterns); buffer = new StringBuilder(); // quit the loops return response; } } // Check for intermediate prompts Enumeration<String> iterator = intermediatePrompts.keys(); while (iterator.hasMoreElements()) { String currentKey = iterator.nextElement(); if (currentResponse.endsWith(currentKey)) { // Intermediate prompt detected logger.debug("Intermediate prompt detected, sending continue character:" + intermediatePrompts.get(currentKey)); outPrint.println(intermediatePrompts.get(currentKey).toCharArray()); stringsToRemove.add(currentKey); // quit the loop break; } } } } // return the response return response; } catch (IOException e) { logger.debug("Connection Lost!" + e.getMessage()); throw e; } } }