new xt shell based on JS transparency layer
[org.ibex.xt-crawshaw.git] / src / java / org / ibex / xt / shell / Shell.java
index 17a2f57..f677f28 100644 (file)
@@ -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,22 +25,95 @@ 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 <tt>scope</tt> in <tt>root</tt>. */
+    private Object[] path;
+
+    /** Returns the object represented by the given path,
+     *  ignoring the current shell path context.*/
+    public Object getFromPath(Object[] path) throws NoSuchPathException, 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.NoSuchPathException();
+                cur = (JS)o;
+            }
+            return cur.get(path[path.length - 1]);
+        }
+    }
+
+    /** Set the current path of the shell, modifiying the result of getScope(). */
+    public void setPath(Object[] s) throws NoSuchPathException {
+        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 NoSuchPathException(); }
+            if (o == null || !(o instanceof JS)) throw new NoSuchPathException();
+            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.Set(),
-            new Command.Help()
+            new Command.Ls(this),
+            new Command.Pwd(this),
+            new Command.Cd(this),
+            new Command.Rm(this),
+            new Command.Help(this)
         };
     }
 
@@ -46,7 +122,7 @@ 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;
@@ -84,47 +160,19 @@ public class Shell extends Env {
 
             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 NoSuchPathException extends Exception {}
 }