From fb709fba092d5297ead99c5da6fbbd6b77f0214a Mon Sep 17 00:00:00 2001
From: Peter Hormanns <peter.hormanns@jalin.de>
Date: Wed, 28 Nov 2012 15:57:29 +0100
Subject: [PATCH] introduce jline line editing features

---
 hsarjcli/.classpath                               |    1 
 hsarjcli/src/de/hsadmin/jscli/Main.java           |   40 ++++--------
 hsarjcli/src/de/hsadmin/jscli/ConsoleWrapper.java |   62 ++++++++++++++++++++
 hsarjcli/src/de/hsadmin/jscli/ScriptClient.java   |   23 ++++++-
 hsarjcli/lib/jline-1.0.jar                        |    0 
 hsarjcli/src/de/hsadmin/jscli/CASTicket.java      |   27 +++-----
 6 files changed, 107 insertions(+), 46 deletions(-)

diff --git a/hsarjcli/.classpath b/hsarjcli/.classpath
index 30d5f00..20e5ff1 100644
--- a/hsarjcli/.classpath
+++ b/hsarjcli/.classpath
@@ -6,5 +6,6 @@
 	<classpathentry kind="lib" path="lib/xmlrpc-client-3.1.jar"/>
 	<classpathentry kind="lib" path="lib/xmlrpc-common-3.1.jar"/>
 	<classpathentry kind="lib" path="lib/ws-commons-util-1.0.1.jar"/>
+	<classpathentry kind="lib" path="lib/jline-1.0.jar"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/hsarjcli/lib/jline-1.0.jar b/hsarjcli/lib/jline-1.0.jar
new file mode 100644
index 0000000..0089779
--- /dev/null
+++ b/hsarjcli/lib/jline-1.0.jar
Binary files differ
diff --git a/hsarjcli/src/de/hsadmin/jscli/CASTicket.java b/hsarjcli/src/de/hsadmin/jscli/CASTicket.java
index 6ec99fa..e61eaaa 100644
--- a/hsarjcli/src/de/hsadmin/jscli/CASTicket.java
+++ b/hsarjcli/src/de/hsadmin/jscli/CASTicket.java
@@ -2,7 +2,6 @@
 
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
-import java.io.Console;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FileReader;
@@ -22,13 +21,16 @@
 	private static final String LOGIN_URL = "https://login.hostsharing.net:443/cas/v1/tickets";
 	private static final String BACKEND_URL = "https://admin.hostsharing.net:443/hsar/backend";
 
-	private String loginURL;
-	private String backendURL;
-	private String grantingTicket;
-	private String runAs;
-	private String user;
+	final private String loginURL;
+	final private String backendURL;
+	final private String runAs;
+	final private String user;
+	final private ConsoleWrapper cons;
 
-	public CASTicket(String user, String runAs) throws JSCliException {
+	private String grantingTicket;
+
+	public CASTicket(ConsoleWrapper console, String user, String runAs) throws JSCliException {
+		this.cons = console;
 		this.user = user;
 		this.runAs = runAs;
 		Config config = Config.getInstance();
@@ -77,16 +79,7 @@
 	}
 
 	private String readPasswordFromConsole() throws JSCliException {
-		char[] password = null;
-		Console console = System.console();
-		if (console == null) {
-			throw new JSCliException("fatal error: console not found");
-		}
-		password = console.readPassword("password:");
-		if (password == null || password.length <= 0) {
-			throw new JSCliException("no password given");
-		}
-		return new String(password);
+		return cons.readPassword();
 	}
 
 	private String doHttpPost(String urlString, String encodedParams) throws JSCliException {
diff --git a/hsarjcli/src/de/hsadmin/jscli/ConsoleWrapper.java b/hsarjcli/src/de/hsadmin/jscli/ConsoleWrapper.java
new file mode 100644
index 0000000..28f1a44
--- /dev/null
+++ b/hsarjcli/src/de/hsadmin/jscli/ConsoleWrapper.java
@@ -0,0 +1,62 @@
+package de.hsadmin.jscli;
+
+import java.io.IOException;
+
+import jline.ConsoleReader;
+import jline.SimpleCompletor;
+
+public class ConsoleWrapper {
+
+	private ConsoleReader cons;
+	private String prompt;
+
+	public void open(final String prompt) throws JSCliException {
+		this.prompt = prompt;
+		try {
+			cons = new ConsoleReader();
+			cons.setDefaultPrompt(prompt);
+		} catch (IOException e) {
+			throw new JSCliException(e);
+		}
+	}
+
+	public String readInput() throws JSCliException {
+		try {
+			String line = cons.readLine();
+			while (line.trim().endsWith("\\")) {
+				line = line.substring(0, line.length() - 1) + "\n" + cons.readLine(">");
+			}
+			return line;
+		} catch (IOException e) {
+			throw new JSCliException(e);
+		}
+	}
+	
+	public void println(String text) throws JSCliException {
+		try {
+			if (cons != null) {
+				cons.printString(text);
+				cons.printNewline();
+			} else {
+				throw new JSCliException("cannot write console");
+			}
+		} catch (IOException e) {
+			throw new JSCliException(e);
+		}
+	}
+
+	public String readPassword() throws JSCliException {
+		try {
+			String pw = cons.readLine("password:", new Character('*'));
+			cons.setDefaultPrompt(prompt);
+			return pw;
+		} catch (IOException e) {
+			throw new JSCliException(e);
+		}
+	}
+
+	public void codeCompletion(String[] candidateStrings) {
+		cons.addCompletor(new SimpleCompletor(candidateStrings));
+	}
+
+}
diff --git a/hsarjcli/src/de/hsadmin/jscli/Main.java b/hsarjcli/src/de/hsadmin/jscli/Main.java
index 11d0675..7eec1a5 100644
--- a/hsarjcli/src/de/hsadmin/jscli/Main.java
+++ b/hsarjcli/src/de/hsadmin/jscli/Main.java
@@ -1,6 +1,5 @@
 package de.hsadmin.jscli;
 
-import java.io.Console;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FileReader;
@@ -10,19 +9,22 @@
 public class Main {
 
 	public static void main(String[] args) {
+		ConsoleWrapper console = null;
 		try {
-			JSONFormatter formatter = new JSONFormatter();
 			CommandlineParser cmdParser = new CommandlineParser(args);
 			String runAs = cmdParser.getRunAs();
-			ScriptClient scriptClient = new ScriptClient(cmdParser.getUser(), runAs);
+			console = new ConsoleWrapper();
+			console.open(runAs + "@hsadmin>");
+			JSONFormatter formatter = new JSONFormatter();
+			ScriptClient scriptClient = new ScriptClient(console, cmdParser.getUser(), runAs);
 			String file = cmdParser.getFile();
 			if (file != null && file.length() > 0) {
 				if ("-".equals(file)) {
-					System.out.println(formatter.format(scriptClient.execute(new InputStreamReader(System.in))));
+					console.println(formatter.format(scriptClient.execute(new InputStreamReader(System.in))));
 				} else {
 					File fileHandle = new File(file);
 					try {
-						System.out.println(formatter.format(scriptClient.execute(new FileReader(fileHandle))));
+						console.println(formatter.format(scriptClient.execute(new FileReader(fileHandle))));
 					} catch (FileNotFoundException e) {
 						System.err.println("file not found: " + file);
 					}
@@ -30,37 +32,23 @@
 			}
 			String expr = cmdParser.getExpression();
 			if (expr != null && expr.length() > 0) {
-				System.out.println(formatter.format(scriptClient.execute(expr)));
+				console.println(formatter.format(scriptClient.execute(expr)));
 			}
 			if (cmdParser.isInteractive()) {
-				Console console = System.console();
-				if (console == null) {
-					throw new JSCliException("fatal error: console not found");
-				}
-				String command = console.readLine("%s@hsadmin>", runAs);
-				if (command == null) {
-					command = "";
-				}
+				String command = console.readInput();
 				while (!("bye".equals(command.trim()) || "exit".equals(command.trim()) || "quit".equals(command.trim()))) {
 					try {
-						console.printf("%s\n", formatter.format(scriptClient.execute(command)));
+						console.println(formatter.format(scriptClient.execute(command)));
 					} catch (Exception e) {
-						console.printf("ERR: %s\n", e.getLocalizedMessage());
+						console.println("ERR: " + e.getLocalizedMessage() + "\n");
 					}
-					command = console.readLine("%s@hsadmin>", runAs);
-					if (command == null) {
-						command = "";
-					}
-					while (command.trim().endsWith("\\")) {
-						command = command.substring(0, command.length() - 1) + 
-								"\n" + console.readLine(">");
-					}
+					command = console.readInput();
 				}
 			}
-		} catch (JSCliException e) {
+		} catch (Exception e) {
 			System.err.println(e.getMessage());
 			System.exit(-1);
 		}
 	}
-	
+
 }
diff --git a/hsarjcli/src/de/hsadmin/jscli/ScriptClient.java b/hsarjcli/src/de/hsadmin/jscli/ScriptClient.java
index 762773b..adfc9ad 100644
--- a/hsarjcli/src/de/hsadmin/jscli/ScriptClient.java
+++ b/hsarjcli/src/de/hsadmin/jscli/ScriptClient.java
@@ -1,7 +1,9 @@
 package de.hsadmin.jscli;
 
 import java.io.Reader;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 import javax.script.ScriptEngine;
 import javax.script.ScriptEngineManager;
@@ -9,10 +11,12 @@
 
 public class ScriptClient {
 
-	private ScriptEngine engine;
+	final private ScriptEngine engine;
+	final private Set<String> completionStrings;
 
-	public ScriptClient(String user, String runAs) throws JSCliException {
-		CASTicket grantingTicket = new CASTicket(user, runAs);
+	public ScriptClient(ConsoleWrapper console, String user, String runAs) throws JSCliException {
+		completionStrings = new HashSet<String>();
+		CASTicket grantingTicket = new CASTicket(console, user, runAs);
 		RpcClient rpcClient = new RpcClient(grantingTicket);
 		ScriptEngineManager engineManager = new ScriptEngineManager();
 		engine = engineManager.getEngineByName("js");
@@ -54,6 +58,8 @@
 				if ("delete".equals(function)) {
 					function = "remove";
 				}
+				completionStrings.add(module);
+				completionStrings.add(module + "." + function);
 				try {
 					engine.eval("if (typeof " + module + " === 'undefined') " +
 								"{ var " + module + " = { }; };\n" +
@@ -73,6 +79,17 @@
 				}
 			}
 		}
+		console.codeCompletion(getCodeCompletionStrings());
+	}
+	
+	public String[] getCodeCompletionStrings() {
+		String[] codeCompletionStrings = new String[completionStrings.size()];
+		int idx = 0;
+		for (String s : completionStrings) {
+			codeCompletionStrings[idx] = s;
+			idx++;
+		}
+		return codeCompletionStrings;
 	}
 
 	public Object execute(String snippet) throws JSCliException {

--
Gitblit v1.9.0-SNAPSHOT