From 3b3d88ff92477dabf6eef4dccf2bf388a3ff1388 Mon Sep 17 00:00:00 2001 From: crawshaw Date: Sat, 27 Nov 2004 16:29:37 +0000 Subject: [PATCH] introduce a shell command object darcs-hash:20041127162937-2eb37-a63f187e896d9793e42e26e2b1b73985650bd83d.gz --- src/java/org/ibex/xt/Shell.java | 215 ++++++++++++++++++++++++++------------- 1 file changed, 143 insertions(+), 72 deletions(-) diff --git a/src/java/org/ibex/xt/Shell.java b/src/java/org/ibex/xt/Shell.java index 0f228ab..1596630 100644 --- a/src/java/org/ibex/xt/Shell.java +++ b/src/java/org/ibex/xt/Shell.java @@ -4,15 +4,11 @@ import java.io.*; import java.net.*; import java.util.*; import java.util.regex.*; -import javax.servlet.*; -import javax.servlet.http.*; import org.ibex.util.*; import org.ibex.util.Collections; import org.ibex.js.*; -import org.prevayler.*; - public class Shell { public static void main(String[] args) throws Exception { @@ -22,7 +18,7 @@ public class Shell { Shell shell = new Shell(new URL(args[0])); if (args.length == 2) { - System.out.println(shell.execute(args[1])); + // FIXME } else { shell.listen(new InputStreamReader(System.in), new OutputStreamWriter(System.out)); } @@ -32,11 +28,17 @@ public class Shell { System.out.println("Usage: xish url [command]"); } + protected Command[] commands = new Command[] { + new LsCommand(), + new PwdCommand(), + new HelpCommand() + }; + /** URL of server. */ - private URL server; + protected URL server; /** Current JS path using '.' as a seperator. */ - private String pwd = "."; + protected String pwd = "."; /** Create a new Shell using the given url for the server. */ public Shell(URL url) { server = url; } @@ -45,7 +47,7 @@ public class Shell { LineNumberReader in = new LineNumberReader(r); PrintWriter out = new PrintWriter(w); - out.println("Ibex xt shell. Type help or exit."); + out.println("ibex xt shell: type help or exit"); out.print("xt: "); out.flush(); @@ -64,99 +66,168 @@ public class Shell { } if (buffer.length() > 0) { - execute(buffer, out); + String[] c = buffer.split(" "); + int i=0; while (i < commands.length) { + if (commands[i].name().equals(c[0])) { + commands[i].execute(out, c); + out.write('\n'); break; + } + i++; + } + if (i == commands.length) { + out.write(c[0]); + w.write(": command not found\n"); + } buffer = ""; - } else { - out.println(""); } out.print("xt: "); out.flush(); } } - public String execute(String cmd) throws IOException { - StringWriter s = new StringWriter(); - execute(cmd, s); - return s.toString(); + private String cookie = null; + public Object send(Request request) throws IOException { + URLConnection c = server.openConnection(); + ((HttpURLConnection)c).setRequestMethod("POST"); + c.setDoOutput(true); + if (cookie != null) c.setRequestProperty("Cookie", cookie); + + c.connect(); + + ObjectOutputStream out = new ObjectOutputStream(c.getOutputStream()); + out.writeObject(request); + out.close(); + + String cook = c.getHeaderField("Set-Cookie"); + if (cook != null && !cook.equals("")) cookie = cook.substring(0, cook.indexOf(';')); + + try { + return new ObjectInputStream(c.getInputStream()).readObject(); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + throw new IOException("unexpected ClassNotFoundException"); + } + } + + public abstract class Command { + /** Returns the command name. */ + public abstract String name(); + + /** Returns single-line of usage information, eg. pattern] */ + public abstract String usage(); + + /** Returns single-line description of command. */ + public abstract String summary(); + + /** Returns multi-line description. */ + public abstract String help(); + + /** Writes result of execution, even if result is an error. */ + public abstract void execute(Writer w, String[] args) throws IOException; + } + + /** Returns the command matching the given name. */ + protected Command command(String name) { + for (int i=0; i < commands.length; i++) + if (commands[i].name().equals(name)) return commands[i]; + return null; + } + + public class HelpCommand extends Command { + public String name() { return "help"; } + public String usage() { return "[command name]"; } + public String summary() { return "Lists available commands."; } + public String help() { return ""; } + + public void execute(Writer w, String[] c) throws IOException { + if (c.length > 1) { + Command cmd = command(c[1]); + if (c == null) { + w.write("help: "); + w.write(c[1]); + w.write(": command not found"); + } else { + w.write("usage: "); + w.write(cmd.name()); + w.write(" "); + w.write(cmd.usage()); + w.write("\n\n"); + w.write(cmd.help()); + w.write("\n"); + } + } else { + int len = 3; + for (int i=0; i < commands.length; i++) + len = Math.max(commands[i].name().length(), len); + + w.write("Available commands:\n"); + for (int i=0; i < commands.length; i++) { + Command cmd = commands[i]; + w.write(" "); + w.write(cmd.name()); + for (int j=len - cmd.name().length(); j >= 0; j--) w.write(" "); + w.write(" - "); + w.write(cmd.summary()); + w.write("\n"); + } + w.write("\nFor usage details, type help [command name]."); + } + } } - public void execute(String cmd, Writer w) throws IOException { - if (cmd == null || cmd.length() == 0) return; - String[] c = cmd.split(" "); + public class LsCommand extends Command { + public String name() { return "ls"; } + public String usage() { return "[path]"; } + public String summary() { return "List object entries."; } + public String help() { return + "The ls command, modelled after the UNIX ls command lists the " + + "keys in an object. "; + } + + public void execute(Writer w, String[] c) throws IOException { + if (c.length > 2) { w.write(usage()); return; } - //#switch(c[0]) - case "ls": - if (c.length > 2) { w.write("usage: ls [path]\n"); return; } String path = pwd; String matcher = ".*"; if (c.length == 2) { - int pos = c[1].lastIndexOf('/'); + int pos = c[1].lastIndexOf('/') + 1; path += c[1].substring(0, pos); - path.replaceAll("/", "\\."); - if (pos + 1 < c[1].length()) { - matcher = c[1].substring(pos + 1); - matcher.replaceAll("\\.", "\\."); - matcher.replaceAll("\\*", ".*"); + path = path.replaceAll("/", "\\."); + if (pos < c[1].length()) { + matcher = c[1].substring(pos); + matcher = matcher.replaceAll("\\.", "\\."); + matcher = matcher.replaceAll("\\*", ".*"); } } Object ret = send(new KeyRequest(path, matcher)); if (ret == null) { - error(w, "returned object is null"); return; + w.write("error: (unexpected) returned object is null"); } else if (ret instanceof JSExn) { - error(w, (JSExn)ret); return; + w.write("error: "); + w.write(((JSExn)ret).getMessage()); } else if (ret instanceof List) { List l = (List)ret; Collections.sort(l); + w.write("total items: "); + w.write(l.size()+""); Iterator i = l.iterator(); while (i.hasNext()) { - w.write(" "); + w.write("\n "); w.write(i.next().toString()); - w.write("\n"); } - return; } else { - error(w, "returned object of unknown type: "+ret.getClass().getName());return; + w.write("error: (unexpected) returned object is of unknown type: "); + w.write(ret.getClass().getName()); } - case "pwd": - w.write(pwd.replace('.', '/')); - w.write("\n"); - case "cd": - throw new Error("not yet implemented"); - case "help": - w.write("Available commands:\n"); - w.write(" ls - list entries in current object\n"); - w.write(" pwd - path of current object\n"); - w.write(" help - this message\n"); - w.write(" exit - close xt shell\n"); - //#end - } - - public void error(Writer w, String s) throws IOException { - w.write("Unexpected error: "); - w.write(s); - w.write("\n"); - } - - public void error(Writer w, JSExn e) throws IOException { - w.write("\nerror: "); - w.write(e.getMessage()); - w.write('\n'); + } } - public Object send(Request request) throws IOException { - URLConnection c = server.openConnection(); - ((HttpURLConnection)c).setRequestMethod("POST"); - c.setDoOutput(true); - c.connect(); - - ObjectOutputStream out = new ObjectOutputStream(c.getOutputStream()); - out.writeObject(request); - out.close(); - - try { - return new ObjectInputStream(c.getInputStream()).readObject(); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - throw new IOException("unexpected ClassNotFoundException"); + public class PwdCommand extends Command { + public String name() { return "pwd"; } + public String usage() { return ""; } + public String summary() { return "Path to current object."; } + public String help() { return "Print the path to the current object."; } + public void execute(Writer w, String[] c) throws IOException { + w.write(c.length == 1 ? pwd.replace('.', '/') : usage()); } } -- 1.7.10.4