X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Fjava%2Forg%2Fibex%2Fxt%2Fshell%2FShell.java;h=ceef6bf1e54d453f8392d963f418fef795c4eede;hb=8dcd09248633282c9ec641b56c00ea3d95d790e7;hp=746479ed20b534ef9fff876bc8f1994415ea66fe;hpb=79f04e59b0a9997c56f0bc3859be30f6fd262717;p=org.ibex.xt-crawshaw.git diff --git a/src/java/org/ibex/xt/shell/Shell.java b/src/java/org/ibex/xt/shell/Shell.java index 746479e..ceef6bf 100644 --- a/src/java/org/ibex/xt/shell/Shell.java +++ b/src/java/org/ibex/xt/shell/Shell.java @@ -3,7 +3,10 @@ package org.ibex.xt.shell; import java.io.*; import java.net.*; -public class Shell extends Env { +import org.ibex.js.*; +import org.ibex.util.*; + +public class Shell { public static void main(String[] args) throws Exception { if (args.length == 0 || args.length > 2|| !args[0].startsWith("http://")) { @@ -22,21 +25,106 @@ public class Shell extends Env { System.out.println("Usage: xish url [command]"); } - /** URL of server. */ - protected URL server; - /** Server cookie. Reduces server load. */ - private String cookie = null; + /** Supported commands. */ + private Command[] commands; + + /** Root context. */ + private final JS root; + + /** Current JS context for the shell. */ + private JS scope; + + /** Current path to scope in root. */ + private Object[] path; + + /** Returns the object represented by the given path, + * ignoring the current shell path context.*/ + public Object getFromPath(Object[] path) throws BadPathException, JSExn { + if (path.length == 0) return root; + + if (root instanceof JSRemote) { + // JSRemote will automatically process its keys for '.' seperators + StringBuffer sb = new StringBuffer(path[0].toString()); + for (int i=1; i < path.length; i++) { + sb.append('.'); sb.append(path[i].toString()); + } + return root.get(sb.toString()); + } else { + JS cur = root; + for (int i=0; i < path.length - 1; i++) { + Object o = cur.get(path[i]); + if (o == null || !(o instanceof JS)) throw new Shell.BadPathException(); + cur = (JS)o; + } + return cur.get(path[path.length - 1]); + } + } + + public void transaction(JS t) { + if (root instanceof JSRemote) { + ((JSRemote)root).transaction( + JS.cloneWithNewParentScope(t, new JSScope(null))); + } else { + // FIXME JS.eval(JS.cloneWithNewParentScope(t, root)); + } + } + + /** Set the current path of the shell, modifiying the result of getScope(). */ + public void setPath(Object[] s) throws BadPathException { + JS cur = root; + if (s == null) s = new Object[0]; + for (int i=0; i < s.length; i++) { + Object o; + try { o = cur.get(s[i]); } catch (JSExn e) { throw new BadPathException(); } + if (o == null || !(o instanceof JS)) throw new BadPathException(); + cur = (JS)o; + } + scope = cur; + path = s; + } + + /** Returns the current path of the shell. */ + public Object[] getPath() { return path; } + + /** Returns String represntation of path, using '/' as a seperator. */ + public String getPathAsString() { + if (path.length == 0) return "/"; + StringBuffer sb = new StringBuffer(); + for (int i=0; i < path.length; i++) { + sb.append('/'); sb.append(path[i].toString()); + } + return sb.toString(); + } + + /** Returns the context matching the current path. */ + public JS getScope() { return scope; } + + /** Returns the context matching the current path. */ + public JS getRootScope() { return root; } + + /** Returns all supported commands. */ + public Command[] getCommands() { return commands; } + + /** Returns the command matching the given name. */ + public Command getCommand(String name) { + for (int i=0; i < commands.length; i++) + if (commands[i].name().equals(name)) return commands[i]; + return null; + } /** Create a new Shell using the given url for the server. */ public Shell(URL url) { - server = url; + root = scope = new JSRemote(url); + path = new String[0]; commands = new Command[] { - new Command.Ls(), - new Command.Pwd(), - new Command.Cd(), - new Command.Rm(), - new Command.Help() + new Command.Ls(this), + new Command.Pwd(this), + new Command.Cd(this), + new Command.Rm(this), + new Command.Replace(this), + new Command.Mkdir(this), + new Command.Help(this) }; } @@ -45,66 +133,60 @@ public class Shell extends Env { PrintWriter out = new PrintWriter(w); out.println("ibex xt shell: type help or exit"); - out.print("xt: "); + out.print("xt:"); out.print(getPathAsString()); out.print("# "); out.flush(); String line; String buffer = ""; + int countBraceOpen = 0, countBraceClose = 0; + int countBracketOpen = 0, countBracketClose = 0; + int countSQBracketOpen = 0, countSQBracketClose = 0; while ((line = in.readLine()) != null) { if (line.length() > 0) { if (line.startsWith("exit")) return; - if (line.charAt(line.length() - 1) == '\\') { - buffer += line.substring(0, line.length() - 1); - out.print('>'); - out.flush(); continue; + + for (int i=0; i < line.length(); i++) { + switch (line.charAt(i)) { + case '{': countBraceOpen++; break; + case '}': countBraceClose++; break; + case '(': countBracketOpen++; break; + case ')': countBracketClose++; break; + case '[': countSQBracketOpen++; break; + case ']': countSQBracketClose++; break; + } } + boolean nonendchar = line.charAt(line.length() - 1) == '\\'; + if (nonendchar) line = line.substring(0, line.length() - 1); buffer += line; + + if (nonendchar || + countBracketOpen != countBracketClose || + countBraceOpen != countBraceClose || + countSQBracketOpen != countSQBracketClose) { + out.print('>'); + out.flush(); continue; + } } if (buffer.length() > 0) { String[] c = buffer.split(" "); - Command cmd = command(c[0]); + Command cmd = getCommand(c[0]); if (cmd == null) { out.write(c[0]); w.write(": command not found\n"); - } else cmd.execute(out, c, this); + } else cmd.execute(out, c); buffer = ""; } - out.print("xt: "); + out.print("xt:"); out.print(getPathAsString()); out.print("# "); out.flush(); } } - public Request.Response 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 { - Object o = new ObjectInputStream(c.getInputStream()).readObject(); - if (o == null) { - throw new IOException("unexpected null object returned"); - } else if (!(o instanceof Request.Response)) { - throw new IOException("unexpected object returned: "+o.getClass().getName()); - } else { - return (Request.Response)o; - } - } catch (ClassNotFoundException e) { - e.printStackTrace(); - throw new IOException("unexpected ClassNotFoundException"); - } + public static class BadPathException extends Exception { + public BadPathException() {} + public BadPathException(String msg) { super(msg); } } }