+++ /dev/null
-package org.ibex.xt;
-
-import java.io.*;
-import java.net.*;
-import java.util.*;
-import java.util.regex.*;
-
-import org.ibex.util.*;
-import org.ibex.util.Collections;
-import org.ibex.js.*;
-
-public class Shell {
-
- public static void main(String[] args) throws Exception {
- if (args.length == 0 || args.length > 2|| !args[0].startsWith("http://")) {
- printUsage(); return;
- }
- Shell shell = new Shell(new URL(args[0]));
-
- if (args.length == 2) {
- // FIXME
- } else {
- shell.listen(new InputStreamReader(System.in), new OutputStreamWriter(System.out));
- }
- }
-
- private static void printUsage() {
- System.out.println("Usage: xish url [command]");
- }
-
- protected Command[] commands = new Command[] {
- new LsCommand(),
- new PwdCommand(),
- new CdCommand(),
- new RmCommand(),
- new HelpCommand()
- };
-
- /** URL of server. */
- protected URL server;
-
- /** Current JS path using '.' as a seperator. */
- protected String pwd = ".";
-
- /** Create a new Shell using the given url for the server. */
- public Shell(URL url) { server = url; }
-
- public void listen(Reader r, Writer w) throws IOException {
- LineNumberReader in = new LineNumberReader(r);
- PrintWriter out = new PrintWriter(w);
-
- out.println("ibex xt shell: type help or exit");
- out.print("xt: ");
- out.flush();
-
- String line;
- String buffer = "";
- 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;
- }
-
- buffer += line;
- }
-
- if (buffer.length() > 0) {
- String[] c = buffer.split(" ");
- int i=0; while (i < commands.length) {
- if (commands[i].name().equals(c[0])) {
- commands[i].execute(out, c); break;
- }
- i++;
- }
- if (i == commands.length) {
- out.write(c[0]);
- w.write(": command not found\n");
- }
- buffer = "";
- }
- out.print("xt: ");
- out.flush();
- }
- }
-
- /** Returns a path, based on console input. */
- private String path(String c) {
- if (c.equals("") || c.equals(".") || c.equals("/")) {
- c = ".";
- } else if (c.equals("..")) {
- c = c.substring(0, c.lastIndexOf('.'));
- if (c.equals("")) c = ".";
- } else {
- if (c.charAt(0) != '/') c = pwd + c;
- c = c.replaceAll("/+", ".");
- if (c.length() > 1 && c.charAt(c.length() - 1) == '.')
- c = c.substring(0, c.length() - 1);
- }
-
- return c;
- }
-
- private String cookie = null;
- public Object 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 {
- return new ObjectInputStream(c.getInputStream()).readObject();
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- throw new IOException("unexpected ClassNotFoundException");
- }
- }
-
- public abstract class Command {
- /** Returns the command name. */
- public abstract String name();
-
- /** Returns single-line of usage information, eg. <tt>pattern]</tt> */
- public abstract String usage();
-
- /** Returns single-line description of command. */
- public abstract String summary();
-
- /** Returns multi-line description. */
- public abstract String help();
-
- /** Writes result of execution, even if result is an error. */
- public abstract void execute(Writer w, String[] args) throws IOException;
- }
-
- /** Returns the command matching the given name. */
- protected Command command(String name) {
- for (int i=0; i < commands.length; i++)
- if (commands[i].name().equals(name)) return commands[i];
- return null;
- }
-
- public class HelpCommand extends Command {
- public String name() { return "help"; }
- public String usage() { return "[command name]"; }
- public String summary() { return "Lists available commands."; }
- public String help() { return ""; }
-
- public void execute(Writer w, String[] c) throws IOException {
- if (c.length > 1) {
- Command cmd = command(c[1]);
- if (c == null) {
- w.write("help: ");
- w.write(c[1]);
- w.write(": command not found\n");
- } else {
- w.write("usage: ");
- w.write(cmd.name());
- w.write(" ");
- w.write(cmd.usage());
- w.write("\n\n");
- w.write(cmd.help());
- w.write("\n");
- }
- } else {
- int len = 3;
- for (int i=0; i < commands.length; i++)
- len = Math.max(commands[i].name().length(), len);
-
- w.write("Available commands:\n");
- for (int i=0; i < commands.length; i++) {
- Command cmd = commands[i];
- w.write(" ");
- w.write(cmd.name());
- for (int j=len - cmd.name().length(); j >= 0; j--) w.write(" ");
- w.write(" - ");
- w.write(cmd.summary());
- w.write("\n");
- }
- w.write("\nFor usage details, type help [command name].\n");
- }
- }
- }
-
- public class LsCommand extends Command {
- public String name() { return "ls"; }
- public String usage() { return "[path]"; }
- public String summary() { return "List object entries."; }
- public String help() { return
- "Lists the keys in an object. Modelled after the UNIX ls command.";
- }
-
- public void execute(Writer w, String[] c) throws IOException {
- if (c.length > 2) { w.write(usage()); return; }
-
- Object ret = send(new KeyRequest(path(c[1])));
- if (ret == null) {
- w.write("error: (unexpected) returned object is null\n");
- } else if (ret instanceof JSExn) {
- String e = ((JSExn)ret).getMessage();
- // FIXME: messy way to get info from server
- if (e.endsWith("does not exist")) {
- w.write("ls ");
- w.write(c[1]);
- w.write(": no such path\n");
- } else {
- w.write("error: ");
- w.write(e);
- w.write("\n");
- }
- } else if (ret instanceof List) {
- List l = (List)ret; Collections.sort(l);
- Iterator i = l.iterator(); while (i.hasNext()) {
- w.write(i.next().toString());
- w.write("\n");
- }
- } else {
- w.write("error: (unexpected) returned object is of unknown type: ");
- w.write(ret.getClass().getName());
- w.write("\n");
- }
- }
- }
-
- public class PwdCommand extends Command {
- public String name() { return "pwd"; }
- public String usage() { return ""; }
- public String summary() { return "Path to current object."; }
- public String help() { return "Print the path to the current object."; }
- public void execute(Writer w, String[] c) throws IOException {
- w.write(c.length == 1 ? pwd.replace('.', '/') : usage());
- w.write("\n");
- }
- }
-
- public class CdCommand extends Command {
- public String name() { return "cd"; }
- public String usage() { return "[path]"; }
- public String summary() { return "Change current object."; }
- public String help() { return
- "Chnages the current object that all other commands use "+
- "as the base for running.\n Pass either a relative path "+
- "(e.g. in /prevalent, type cd myob, now in /prevalent/myob) "+
- "or an absolute path (e.g. cd /prevalent/myob).\n\n" +
- "To go up one level, cd .. can be used.";
- }
- public void execute(Writer w, String[] c) throws IOException {
- if (c.length > 2) w.write(usage());
- else if (c.length == 1 || c[1].equals("") || c[1].equals("/")) pwd = ".";
- else if (c[1].equals("..")) {
- String n = pwd.substring(0, pwd.lastIndexOf('.'));
- pwd = n.equals("") ? "." : n;
- } else {
- String n = path(c[1]);
- Object ret = send(new KeyRequest(n));
-
- if (ret == null) {
- w.write("error: (unexpected) server returned null\n");
- } else if (ret instanceof List && ((List)ret).size() == 1) {
- pwd = n;
- } else if (ret instanceof JSExn ||
- (ret instanceof List && ((List)ret).size() == 0)) {
- w.write("cd ");
- w.write(c[1]);
- w.write(": no such path\n");
- } else {
- w.write("error: (unexpected) server returned ");
- w.write(ret.toString());
- w.write("\n");
- }
- }
- }
- }
-
- public class RmCommand extends Command {
- public String name() { return "rm"; }
- public String usage() { 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) { w.write(usage()); }
-
- String[] r = new String[c.length - 1];
- for (int i=0; i < r.length; i++) r[i] = path(c[i + 1]);
- // Object ret = send(new KeyRequest( FIXME: CompositeRequest
- }
- }
-
- public static abstract class Request implements Serializable {
- public abstract Object process(JSScope root) throws JSExn;
- }
-
- public static class KeyRequest extends Request {
- private String path, matcher;
- public KeyRequest() {}
- public KeyRequest(String c) {
- int pos = c.lastIndexOf('.');
- path = c.substring(0, pos);
- matcher = c.substring(pos + 1).replaceAll("\\*+", ".*");
- }
- public KeyRequest(String path, String matcher) {
- this.path = path; this.matcher = matcher;
- }
-
- /** Returns a List. */
- public Object 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()));
- throw new JSExn("path /" + p + " does not exist");
- } 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 keys;
- }
- }
- }
-
- public static class ExecRequest extends Request {
- private JS exec;
- public ExecRequest() {}
- public ExecRequest(JS exec) { this.exec = exec; }
- public ExecRequest(String source) throws IOException, JSExn {
- this(new StringReader(source));
- }
- public ExecRequest(Reader source) throws IOException, JSExn {
- exec = JS.fromReader("xsh", 0, source);
- }
-
- /** Returns the result of <tt>JS.eval()</tt>. */
- public Object process(JSScope root) throws JSExn {
- return JS.eval(JS.cloneWithNewParentScope(exec, root));
- }
- }
-}
--- /dev/null
+package org.ibex.xt.shell;
+
+import java.util.*;
+
+import java.io.Writer;
+import java.io.IOException;
+
+public abstract class Command {
+ /** Returns the command name. */
+ public abstract String name();
+
+ /** Returns single-line of usage information, eg. <tt>pattern]</tt> */
+ public abstract String usage();
+
+ /** Returns single-line description of command. */
+ public abstract String summary();
+
+ /** Returns multi-line description. */
+ public abstract String help();
+
+ /** Writes result of execution, even if result is an error. */
+ public abstract void execute(Writer w, String[] args, Env env) throws IOException;
+
+ public static class Help extends Command {
+ public String name() { return "help"; }
+ public String usage() { return "[command name]"; }
+ public String summary() { return "Lists available commands."; }
+ public String help() { return ""; }
+
+ public void execute(Writer w, String[] c, Env env) throws IOException {
+ if (c.length > 1) {
+ Command cmd = env.command(c[1]);
+ if (c == null) {
+ w.write("help: ");
+ w.write(c[1]);
+ w.write(": command not found\n");
+ } else {
+ w.write("usage: ");
+ w.write(cmd.name());
+ w.write(" ");
+ w.write(cmd.usage());
+ w.write("\n\n");
+ w.write(cmd.help());
+ w.write("\n");
+ }
+ } else {
+ int len = 3;
+ for (int i=0; i < env.commands.length; i++)
+ len = Math.max(env.commands[i].name().length(), len);
+
+ w.write("Available commands:\n");
+ for (int i=0; i < env.commands.length; i++) {
+ Command cmd = env.commands[i];
+ w.write(" ");
+ w.write(cmd.name());
+ for (int j=len - cmd.name().length(); j >= 0; j--) w.write(" ");
+ w.write(" - ");
+ w.write(cmd.summary());
+ w.write("\n");
+ }
+ w.write("\nFor usage details, type help [command name].\n");
+ }
+ }
+ }
+
+ public static class Ls extends Command {
+ public String name() { return "ls"; }
+ public String usage() { return "[path]"; }
+ public String summary() { return "List object entries."; }
+ public String help() { return
+ "Lists the keys in an object. Modelled after the UNIX ls command.";
+ }
+
+ public void execute(Writer w, String[] c, Env env) throws IOException {
+ if (c.length > 2) { w.write(usage()); return; }
+ String p = env.path(c.length == 1 ? "*" : c[1]);
+
+ Request.Response ret = env.send(new Request.Key(p));
+ if (!(ret instanceof Request.Key.Res)) {
+ w.write("error: ");
+ w.write(ret.error().getMessage());
+ w.write("\n");
+ } else {
+ List l = ((Request.Key.Res)ret).keys();
+ Iterator i = l.iterator(); while (i.hasNext()) {
+ w.write(i.next().toString());
+ w.write("\n");
+ }
+ }
+ }
+ }
+
+ public static class Pwd extends Command {
+ public String name() { return "pwd"; }
+ public String usage() { return ""; }
+ public String summary() { return "Path to current object."; }
+ public String help() { return "Print the path to the current object."; }
+ public void execute(Writer w, String[] c, Env env) throws IOException {
+ if (c.length != 1) { w.write(usage()); return; }
+ w.write(env.path.equals("") ? "/" : env.path.replace('.', '/'));
+ w.write("\n");
+ }
+ }
+
+ public static class Cd extends Command {
+ public String name() { return "cd"; }
+ public String usage() { return "[path]"; }
+ public String summary() { return "Change current object."; }
+ public String help() { return
+ "Chnages the current object that all other commands use "+
+ "as the base for running.\n Pass either a relative path "+
+ "(e.g. in /prevalent, type cd myob, now in /prevalent/myob) "+
+ "or an absolute path (e.g. cd /prevalent/myob).\n\n" +
+ "To go up one level, cd .. can be used.";
+ }
+ public void execute(Writer w, String[] c, Env env) throws IOException {
+ if (c.length > 2) w.write(usage());
+ else if (c.length == 1 || c[1].equals("") || c[1].equals("/")) env.path = "";
+ else if (c[1].equals("..")) {
+ String n = env.path;
+ n = n.substring(0, n.lastIndexOf('.'));
+ env.path = n;
+ } else {
+ String n = env.path(c[1]);
+
+ Request.Response ret = env.send(new Request.Key(n));
+ if (!(ret instanceof Request.Key.Res)) {
+ w.write("error: ");
+ w.write(ret.error().getMessage());
+ w.write("\n");
+ } else {
+ List l = ((Request.Key.Res)ret).keys();
+ if (l.size() == 0) {
+ w.write("cd ");
+ w.write(c[1]);
+ w.write(": no such path\n");
+ } else {
+ env.path = n;
+ }
+ }
+ }
+ }
+ }
+
+ public static class Rm extends Command {
+ public String name() { return "rm"; }
+ public String usage() { return "[options] [path]"; }
+ public String summary() { return "Removes objects."; }
+ public String help() { return "Removes objects."; } // FIXME
+ public void execute(Writer w, String[] c, Env env) throws IOException {
+ if (c.length == 1) { w.write(usage()); }
+
+ String[] r = new String[c.length - 1];
+ for (int i=0; i < r.length; i++) r[i] = env.path(c[i + 1]);
+ // Object ret = send(new KeyRequest( FIXME: CompositeRequest
+ }
+ }
+
+
+}
--- /dev/null
+package org.ibex.xt.shell;
+
+import java.io.IOException;
+
+public abstract class Env {
+ /** Current JS path using '.' as a seperator. */
+ public String path = "";
+
+ public Command[] commands = new Command[0];
+
+ /** Returns the command matching the given name. */
+ public Command command(String name) {
+ for (int i=0; i < commands.length; i++)
+ if (commands[i].name().equals(name)) return commands[i];
+ return null;
+ }
+
+ /** Returns a path, based on console-style representation. */
+ public String path(String c) {
+ if (c.equals("") || c.equals(".") || c.equals("/")) {
+ c = ".";
+ } else if (c.equals("..")) {
+ c = c.substring(0, c.lastIndexOf('.'));
+ if (c.equals("")) c = ".";
+ } else {
+ if (c.charAt(0) != '/') c = path + "." + c;
+ c = c.replaceAll("/+", ".");
+ if (c.length() > 1 && c.charAt(c.length() - 1) == '.')
+ c = c.substring(0, c.length() - 1);
+ }
+ return c;
+ }
+
+ public abstract Request.Response send(Request request) throws IOException;
+}
--- /dev/null
+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; }
+ }
+ }
+}
-package org.ibex.xt;
+package org.ibex.xt.shell;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
+import org.ibex.xt.Prevalence;
import org.ibex.js.*;
import org.prevayler.*;
-
-public class ShellServlet extends HttpServlet {
+public class Servlet extends HttpServlet {
private ServletContext cx = null;
private Prevayler prevayler;
private JS prevalent;
}
public void doPost(HttpServletRequest rq, HttpServletResponse rs) throws IOException {
- Shell.Request r;
- try { r = (Shell.Request)new ObjectInputStream(rq.getInputStream()).readObject(); }
+ Request r;
+ try { r = (Request)new ObjectInputStream(rq.getInputStream()).readObject(); }
catch (ClassNotFoundException e) {
e.printStackTrace();
throw new IOException("exception receiving request, class not found");
}
rq.getSession().setAttribute("scope", scope);
}
- Object ret;
- try { ret = r.process(scope); } catch (JSExn e) { ret = e; }
+ Request.Response ret;
+ try { ret = r.process(scope); } catch (JSExn e) { ret = new Request.Response(e); }
new ObjectOutputStream(rs.getOutputStream()).writeObject(ret);
}
}
--- /dev/null
+package org.ibex.xt.shell;
+
+import java.io.*;
+import java.net.*;
+
+public class Shell extends Env {
+
+ public static void main(String[] args) throws Exception {
+ if (args.length == 0 || args.length > 2|| !args[0].startsWith("http://")) {
+ printUsage(); return;
+ }
+ Shell shell = new Shell(new URL(args[0]));
+
+ if (args.length == 2) {
+ // FIXME
+ } else {
+ shell.listen(new InputStreamReader(System.in), new OutputStreamWriter(System.out));
+ }
+ }
+
+ private static void printUsage() {
+ System.out.println("Usage: xish url [command]");
+ }
+
+ /** URL of server. */
+ protected URL server;
+
+ /** Server cookie. Reduces server load. */
+ private String cookie = null;
+
+ /** Create a new Shell using the given url for the server. */
+ public Shell(URL url) {
+ server = url;
+ commands = new Command[] {
+ new Command.Ls(),
+ new Command.Pwd(),
+ new Command.Cd(),
+ new Command.Rm(),
+ new Command.Help()
+ };
+ }
+
+ public void listen(Reader r, Writer w) throws IOException {
+ LineNumberReader in = new LineNumberReader(r);
+ PrintWriter out = new PrintWriter(w);
+
+ out.println("ibex xt shell: type help or exit");
+ out.print("xt: ");
+ out.flush();
+
+ String line;
+ String buffer = "";
+ 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;
+ }
+
+ buffer += line;
+ }
+
+ if (buffer.length() > 0) {
+ String[] c = buffer.split(" ");
+ Command cmd = command(c[0]);
+
+ if (cmd == null) {
+ out.write(c[0]);
+ w.write(": command not found\n");
+ } else cmd.execute(out, c, this);
+
+ buffer = "";
+ }
+ out.print("xt: ");
+ 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");
+ }
+ }
+}