improve ls output
[org.ibex.xt-crawshaw.git] / src / java / org / ibex / xt / shell / Request.java
index f0d3697..8cb2be6 100644 (file)
@@ -45,7 +45,9 @@ public abstract class Request implements Serializable {
 
         /** Returns the keys in <tt>js</tt> that match <tt>matcher</tt>. */
         protected List matches(JS js) throws JSExn {
-            Pattern pat = Pattern.compile(matcher);
+            String m = matcher;
+
+            Pattern pat = Pattern.compile(m);
             List keys = new ArrayList();
 
             Iterator i = js.keys().iterator(); while(i.hasNext()) {
@@ -69,6 +71,11 @@ public abstract class Request implements Serializable {
 
         public Response process(JSScope root) throws JSExn {
             JS js = keyed(path(root));
+
+            // if matcher is exact and a keyed object, return its keys
+            JS o = keyed(js.get(matcher));
+            if (o != null) { js = o; matcher = ".*"; }
+
             return js == null ? new Res() : new Res(matches(js));
         }
 
@@ -81,6 +88,22 @@ public abstract class Request implements Serializable {
         }
     }
 
+    public static class IsKey extends Key {
+        public IsKey() {}
+        public IsKey(String c) { super(c); }
+        public Response process(JSScope root) throws JSExn {
+            JS js = keyed(path(root));
+            return js == null ? new Res(false) : new Res(js.get(matcher) != null);
+        }
+
+        public static class Res extends Response {
+            private boolean exists;
+            public Res() {}
+            public Res(boolean e) { exists = e; }
+            public boolean exists() { return exists; }
+        }
+    }
+
     public static class RemoveKey extends Key {
         public RemoveKey(String c) { super(c); }
         public RemoveKey(String p, String m) { super(p, m); }
@@ -100,6 +123,45 @@ public abstract class Request implements Serializable {
         }
     }
 
+    public static class SetKey extends Key {
+        protected JS value;
+        public SetKey() {}
+        public SetKey(String p, String m, JS val) { super(p, m); this.value = val; }
+
+        public Response process(JSScope root) throws JSExn {
+            JS js = keyed(path(root));
+            if (js == null) throw new JSExn("no such path");
+
+            js.put(matcher, JS.eval(JS.cloneWithNewParentScope(
+                                    value, new JSResolve(root, js))));
+            return new Res(); // TODO: return put() value when it has one
+        }
+
+        public class Res extends Response {
+        }
+
+        public class JSResolve extends JSScope {
+            private JS path;
+            public JSResolve(JSScope parent, JS path) { super(parent); this.path = path; }
+            public Object get(Object key) throws JSExn {
+                if (key != null && key instanceof String) {
+                    String k = (String)key;
+                    if (k.startsWith(".")) k = k.substring(1);
+                    else return path.get(k);
+                }
+                return super.get(key);
+            }
+            public void put(Object key, Object val) throws JSExn {
+                if (key != null && key instanceof String) {
+                    String k = (String)key;
+                    if (k.startsWith(".")) k = k.substring(1);
+                    else { path.put(key, val); return; }
+                }
+                super.put(key, val);
+            }
+        }
+    }
+
     /** Runs a series of requests. */
     public static class Composite extends Request {
         private boolean breakOnError = false;