give xt.shell its own package
[org.ibex.xt-crawshaw.git] / src / java / org / ibex / xt / shell / Request.java
diff --git a/src/java/org/ibex/xt/shell/Request.java b/src/java/org/ibex/xt/shell/Request.java
new file mode 100644 (file)
index 0000000..eec18b7
--- /dev/null
@@ -0,0 +1,99 @@
+package org.ibex.xt.shell;
+
+import java.io.*;
+import java.util.*;
+import java.util.regex.*;
+
+import org.ibex.js.*;
+
+public abstract class Request implements Serializable {
+
+    public abstract Response process(JSScope root) throws JSExn;
+
+    public static class Response implements Serializable {
+        protected Exception ex;
+        public Response() { ex = null; }
+        public Response(Exception e) { ex = e; }
+        public Exception error() { return ex; }
+    }
+
+    public static class Key extends Request {
+        private String path, matcher;
+        public Key() {}
+        public Key(String c) {
+            int pos = c.lastIndexOf('.');
+            path = c.substring(0, pos);
+            matcher = c.substring(pos + 1).replaceAll("\\*+", ".*");
+        }
+        public Key(String path, String matcher) {
+            this.path = path; this.matcher = matcher;
+        }
+
+        public Response process(JSScope root) throws JSExn {
+            String p = path == null ? "" : path.replaceAll("\\.+", "\\.");
+            if (p.length() > 0 && p.charAt(0) == '.')
+                p = p.substring(1);
+            if (p.length() > 0 && p.charAt(p.length() - 1) == '.')
+                p = p.substring(0, p.length() - 1);
+
+            System.out.println("searching path '"+p+"' for pattern '"+matcher+"'");
+
+            Object o = p.equals("") ? root : root.get(p);
+            if (o == null || o instanceof JSDate ||
+                             o instanceof JSArray ||
+                             !(o instanceof JS)) {
+                System.out.println("hit bad object: "+o+", class="+
+                    (o == null ? null : o.getClass().getName()));
+                return new Key.Res();
+            } else {
+                Pattern pat = Pattern.compile(matcher);
+                List keys = new ArrayList();
+
+                Iterator i = ((JS)o).keys().iterator(); while(i.hasNext()) {
+                    String k = i.next().toString();
+                    if (pat.matcher(k).matches()) keys.add(k);
+                }
+
+                return new Res(keys);
+            }
+        }
+
+        public static class Res extends Response {
+            private List keys;
+            public Res() { keys = null; }
+            public Res(List l) { keys = l; }
+            public List keys() { return keys; }
+            public boolean isPath() { return keys != null; }
+        }
+    }
+
+    public static class Composite extends Request {
+        private Request[] requests;
+        public Composite() {}
+        public Composite(Request[] r) { requests = r; }
+        public Composite(List r) {
+            Request[] req = new Request[r.size()];
+            r.toArray(req);
+            requests = req;
+        }
+
+        public Response process(JSScope root) {
+            Response[] res = new Response[requests.length];
+
+            for (int i=0; i < requests.length; i++) {
+                try { res[i] = requests[i].process(root); }
+                catch (JSExn e) { res[i] = new Response(e); }
+            }
+
+            return new Res(res);
+        }
+
+        public static class Res extends Response {
+            private Response[] responses;
+            public Res() {}
+            public Res(Response[] r) { responses = r; }
+            public Response get(int i) { return responses[i]; }
+            public int size() { return responses.length; }
+        }
+    }
+}