update to handle returning old version from put() function in JS and functional rm...
[org.ibex.xt-crawshaw.git] / src / java / org / ibex / xt / shell / Command.java
index 48fb329..04ca7b1 100644 (file)
@@ -1,5 +1,6 @@
 package org.ibex.xt.shell;
 
+import java.io.StringReader;
 import java.io.Writer;
 import java.io.IOException;
 
@@ -39,14 +40,14 @@ public abstract class Command {
         w.write("\n");
     }
 
-    public List fromShellPath(String s) throws Shell.NoSuchPathException {
+    public List fromShellPath(String s) throws Shell.BadPathException {
         return fromShellPath(s, null);
     }
 
     /** Converts a shell path "/foo/etc/../bar" to its component form,
      *  { "foo", "bar" } and loads it into the returned list.
      *  Handles relative positioning to shell.getPath(). */
-    public List fromShellPath(String s, List l) throws Shell.NoSuchPathException {
+    public List fromShellPath(String s, List l) throws Shell.BadPathException {
         if (s == null) return null;
         if (l == null) l = new ArrayList();
 
@@ -124,7 +125,7 @@ public abstract class Command {
                 Object key = path.remove(path.size() - 1);
                 Object po = shell.getFromPath(path.toArray());
                 if (po == null || !(po instanceof JS))
-                    throw new Shell.NoSuchPathException();
+                    throw new Shell.BadPathException();
                 JS cur = (JS)po;
 
                 if (key instanceof String &&
@@ -145,7 +146,7 @@ public abstract class Command {
                     w.write(key.toString());
                     w.write("\n");
                 }
-            } catch (Shell.NoSuchPathException e) {
+            } catch (Shell.BadPathException e) {
                 w.write("error: no such path: ");
                 w.write(p);
                 w.write("\n");
@@ -159,6 +160,86 @@ public abstract class Command {
         }
     }
 
+    public static class Rm extends Command {
+        public Rm(Shell s) { super(s); }
+        public String name() { return "rm"; }
+        public String params() { return "[options] [path]"; }
+        public String summary() { return "Removes objects."; }
+        public String help() { return "Removes objects."; } // FIXME info
+        public void execute(Writer w, String[] c) throws IOException {
+            if (c.length == 1) { usage(w); return; }
+
+            boolean force = false; // FIXME provide ability to set
+
+            StringBuffer func = new StringBuffer();
+
+            for (int ic=1; ic < c.length; ic++) {
+                String p = c.length == 1 ? "*" : c[ic];
+                if (p.endsWith("/")) p += "*";
+
+                try {
+                    // get the base of the path
+                    List path = fromShellPath(p);
+                    Object key = path.remove(path.size() - 1);
+                    Object po = shell.getFromPath(path.toArray());
+                    if (po == null || !(po instanceof JS))
+                        throw new Shell.BadPathException();
+                    JS cur = (JS)po;
+
+                    if (cur.containsKey(key)) {
+                        Object o = cur.get(key);
+                        if (!force && o != null && o instanceof JS && ((JS)o).keys().size() > 0)
+                            throw new Shell.BadPathException("key is not empty");
+                        func.append("prevalent.");
+                        for(int i=0; i < path.size(); i++) {
+                            func.append(path.get(i)); func.append('.'); }
+                        func.append("Delete(\"");
+                        func.append(key.toString());
+                        func.append("\");\n");
+                    } else if (key instanceof String && ((String)key).indexOf('*') >= 0) {
+                        String last = (String)key;
+                        last = last.replaceAll("\\.", "\\.");
+                        last = last.replaceAll("\\*", ".*");
+                        Pattern pat = Pattern.compile(last);
+                        Collection curkeys = cur.keys();
+                        if (curkeys.size() == 0) throw new Shell.BadPathException();
+                        Iterator it = curkeys.iterator(); while (it.hasNext()) {
+                            Object o = it.next();
+                            if (o == null || !(o instanceof String)) continue;
+                            String s = (String)o;
+                            if (!pat.matcher(s).matches()) continue;
+
+                            func.append("prevalent.");
+                            for(int i=0; i < path.size(); i++) {
+                                func.append(path.get(i)); func.append('.'); }
+                            func.append("Delete(\"");
+                            func.append(s);
+                            func.append("\");\n");
+                        }
+                    } else throw new Shell.BadPathException();
+
+                } catch (JSExn e) {
+                    w.write("error: cannot remove '");
+                    w.write(p);
+                    w.write("': ");
+                    w.write(e.getMessage());
+                    w.write("\n");
+                    return;
+                } catch (Shell.BadPathException e) {
+                    w.write("error: cannot remove '");
+                    w.write(p);
+                    w.write("': ");
+                    w.write(e.getMessage() != null ? e.getMessage() : "no such path");
+                    w.write("\n");
+                    return;
+                }
+            }
+
+            shell.transaction(JS.fromReader(
+                "rm-transaction", 0, new StringReader(func.toString())));
+        }
+    }
+
     public static class Pwd extends Command {
         public Pwd(Shell s) { super(s); }
         public String name() { return "pwd"; }
@@ -194,7 +275,7 @@ public abstract class Command {
             String path = c.length == 1 ? "/" : c[1];
 
             try { shell.setPath(fromShellPath(path).toArray()); }
-            catch (Shell.NoSuchPathException e) {
+            catch (Shell.BadPathException e) {
                 w.write("error: no such path: ");
                 w.write(path);
                 w.write("\n");
@@ -202,15 +283,4 @@ public abstract class Command {
         }
     }
 
-    public static class Rm extends Command {
-        public Rm(Shell s) { super(s); }
-        public String name() { return "rm"; }
-        public String params() { return "[options] [path]"; }
-        public String summary() { return "Removes objects."; }
-        public String help() { return "Removes objects."; } // FIXME
-        public void execute(Writer w, String[] c) throws IOException {
-            if (c.length == 1) { usage(w); return; }
-
-        }
-    }
 }