X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Fjava%2Forg%2Fibex%2Fxt%2Fshell%2FCommand.java;h=48fb3296914e6df8fc814e97e0c74af93a9fe274;hb=e2e46233d9db6fe8728421016a41d5bf79db86e5;hp=7edc5ac65e513558807d53213ae973f67e5c81ca;hpb=a86e3334b03e5acf25fe9223d9d7634573a6c396;p=org.ibex.xt-crawshaw.git diff --git a/src/java/org/ibex/xt/shell/Command.java b/src/java/org/ibex/xt/shell/Command.java index 7edc5ac..48fb329 100644 --- a/src/java/org/ibex/xt/shell/Command.java +++ b/src/java/org/ibex/xt/shell/Command.java @@ -1,19 +1,24 @@ package org.ibex.xt.shell; -import java.io.StringReader; import java.io.Writer; import java.io.IOException; import java.util.*; +import java.util.regex.*; import org.ibex.js.*; +import org.ibex.util.*; public abstract class Command { + protected Shell shell; + + protected Command(Shell s) { shell = s; } + /** Returns the command name. */ public abstract String name(); - /** Returns single-line of usage information, eg. pattern] */ - public abstract String usage(); + /** Returns a single-line of parameter information, eg. [pattern] */ + public abstract String params(); /** Returns single-line description of command. */ public abstract String summary(); @@ -22,38 +27,72 @@ public abstract class Command { 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 abstract void execute(Writer w, String[] args) throws IOException; + + + /** Returns single-line of usage information, eg. usage: ls [pattern] */ + public void usage(Writer w) throws IOException { + w.write("usage: "); + w.write(name()); + w.write(" "); + w.write(params()); + w.write("\n"); + } + + public List fromShellPath(String s) throws Shell.NoSuchPathException { + 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 { + if (s == null) return null; + if (l == null) l = new ArrayList(); + + s = s.trim().replace("/+", "/"); + if (s.charAt(0) != '/') l.addAll(Arrays.asList(shell.getPath())); + + StringTokenizer st = new StringTokenizer(s, "/"); + while (st.hasMoreTokens()) { + String part = st.nextToken(); + if (part == null || part.equals("") || part.equals(".")) continue; + else if (part.equals("..")) { if (l.size() > 0) l.remove(l.size() - 1); } + else l.add(part); + } + + return l; + } public static class Help extends Command { + public Help(Shell s) { super(s); } public String name() { return "help"; } - public String usage() { return "[command name]"; } + public String params() { 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 { + public void execute(Writer w, String[] c) throws IOException { if (c.length > 1) { - Command cmd = env.command(c[1]); + Command cmd = shell.getCommand(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"); + cmd.usage(w); + w.write("\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); + Command[] cmds = shell.getCommands(); + for (int i=0; i < cmds.length; i++) + len = Math.max(cmds[i].name().length(), len); w.write("Available commands:\n"); - for (int i=0; i < env.commands.length; i++) { - Command cmd = env.commands[i]; + for (int i=0; i < cmds.length; i++) { + Command cmd = cmds[i]; w.write(" "); w.write(cmd.name()); for (int j=len - cmd.name().length(); j >= 0; j--) w.write(" "); @@ -67,47 +106,81 @@ public abstract class Command { } public static class Ls extends Command { + public Ls(Shell s) { super(s); } public String name() { return "ls"; } - public String usage() { return "[path]"; } + public String params() { 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()); + public void execute(Writer w, String[] c) throws IOException { + if (c.length > 2) { usage(w); return; } + String p = c.length == 1 ? "*" : c[1]; + if (p.endsWith("/")) p += "*"; + + try { + 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.NoSuchPathException(); + JS cur = (JS)po; + + if (key instanceof String && + ((String)key).indexOf('*') >= 0) { + String last = (String)key; + last = last.replaceAll("\\.", "\\."); + last = last.replaceAll("\\*", ".*"); + Pattern pat = Pattern.compile(last); + Iterator i = cur.keys().iterator(); while (i.hasNext()) { + Object o = i.next(); + if (o == null || !(o instanceof String)) continue; + String s = (String)o; + if (!pat.matcher(s).matches()) continue; + w.write(s); + w.write("\n"); + } + } else if (cur.containsKey(key)) { + w.write(key.toString()); w.write("\n"); } + } catch (Shell.NoSuchPathException e) { + w.write("error: no such path: "); + w.write(p); + w.write("\n"); + } catch (JSExn e) { + w.write("error: no such path: "); + w.write(p); + w.write(" ("); + w.write(e.getMessage()); + w.write(")\n"); } } } public static class Pwd extends Command { + public Pwd(Shell s) { super(s); } public String name() { return "pwd"; } - public String usage() { return ""; } + public String params() { 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); + public void execute(Writer w, String[] c) throws IOException { + if (c.length != 1) { usage(w); return; } + Object[] path = shell.getPath(); + for (int i=0; i < path.length; i++) { + w.write("/"); + w.write(path[i].toString()); + } + if (path.length == 0) w.write("/"); w.write("\n"); } } public static class Cd extends Command { + public Cd(Shell s) { super(s); } public String name() { return "cd"; } - public String usage() { return "[path]"; } + public String params() { return "[path]"; } public String summary() { return "Change current object."; } public String help() { return "Chnages the current object that all other commands use "+ @@ -116,97 +189,28 @@ public abstract class Command { "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.IsKey(n)); - if (!(ret instanceof Request.IsKey.Res)) { - w.write("error: "); - w.write(ret.error().getMessage()); - w.write("\n"); - } else { - if (((Request.IsKey.Res)ret).exists()) { - w.write("error: "); - w.write(c[1]); - w.write(": no such path\n"); - } else { - env.path = n; - } - } + public void execute(Writer w, String[] c) throws IOException { + if (c.length > 2) { usage(w); return; } + String path = c.length == 1 ? "/" : c[1]; + + try { shell.setPath(fromShellPath(path).toArray()); } + catch (Shell.NoSuchPathException e) { + w.write("error: no such path: "); + w.write(path); + w.write("\n"); } } } public static class Rm extends Command { + public Rm(Shell s) { super(s); } public String name() { return "rm"; } - public String usage() { return "[options] [path]"; } + 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, Env env) throws IOException { - if (c.length == 1) { w.write(usage()); } - - Request.Key[] r = new Request.Key[c.length - 1]; - for (int i=0; i < r.length; i++) r[i] = new Request.RemoveKey(env.path(c[i + 1])); + public void execute(Writer w, String[] c) throws IOException { + if (c.length == 1) { usage(w); return; } - Request.Response ret = env.send(new Request.Composite(r, false)); - if (!(ret instanceof Request.Composite.Res)) { - w.write("error: "); - w.write(ret.error().getMessage()); - w.write("\n"); - } else { - Request.Response[] res = ((Request.Composite.Res)ret).responses(); - for (int i=0; i < res.length; i++) { - if (res[i] instanceof Request.RemoveKey.Res) { - boolean rm = ((Request.RemoveKey.Res)res[i]).removed(); - if (!rm) { - w.write("error: cannot remove '"); - w.write(c[i + 1]); - w.write("': no such key\n"); - } - } else { - w.write("error: cannot remove '"); - w.write(c[i + 1]); - w.write("': "); - w.write(res[i].error().getMessage()); - w.write("\n"); - } - } - } } } - - public static class Set extends Command { - public String name() { return "set"; } - public String usage() { return "[name] [object]"; } - public String summary() { return "Sets ."; } - public String help() { return "Removes objects."; } // FIXME - - public void execute(Writer w, String[] c, Env env) throws IOException { - if (c.length < 3) { w.write(usage()); } - - String m = c[1]; - String s = "return ("; - for (int i=2; i < c.length; i++) s += c[i]; - s += ");"; - - JS js; - try { js = JS.fromReader("input", 0, new StringReader(s)); } - catch (IOException e) { - w.write("error: "); - w.write(e.getMessage()); - w.write("\n"); - return; - } - - Request.Response ret = env.send(new Request.SetKey(env.path, m, js)); - } - } - }