f5ad6fb3f6883955e333a25a5990bf377bd64bb5
[org.ibex.xt-crawshaw.git] / src / java / org / ibex / xt / shell / Command.java
1 package org.ibex.xt.shell;
2
3 import java.io.StringReader;
4 import java.io.Writer;
5 import java.io.IOException;
6
7 import java.util.*;
8
9 import org.ibex.js.*;
10
11 public abstract class Command {
12     /** Returns the command name. */
13     public abstract String name();
14
15     /** Returns single-line of usage information, eg. <tt>pattern]</tt> */
16     public abstract String usage();
17
18     /** Returns single-line description of command. */
19     public abstract String summary();
20
21     /** Returns multi-line description. */
22     public abstract String help();
23
24     /** Writes result of execution, even if result is an error. */
25     public abstract void execute(Writer w, String[] args, Env env) throws IOException;
26
27     public static class Help extends Command {
28         public String name() { return "help"; }
29         public String usage() { return "[command name]"; }
30         public String summary() { return "Lists available commands."; }
31         public String help() { return ""; }
32
33         public void execute(Writer w, String[] c, Env env) throws IOException {
34             if (c.length > 1) {
35                 Command cmd = env.command(c[1]);
36                 if (c == null) {
37                     w.write("help: ");
38                     w.write(c[1]);
39                     w.write(": command not found\n");
40                 } else {
41                     w.write("usage: ");
42                     w.write(cmd.name());
43                     w.write(" ");
44                     w.write(cmd.usage());
45                     w.write("\n\n");
46                     w.write(cmd.help());
47                     w.write("\n");
48                 }
49             } else {
50                 int len = 3;
51                 for (int i=0; i < env.commands.length; i++)
52                     len = Math.max(env.commands[i].name().length(), len);
53
54                 w.write("Available commands:\n");
55                 for (int i=0; i < env.commands.length; i++) {
56                     Command cmd = env.commands[i];
57                     w.write("  ");
58                     w.write(cmd.name());
59                     for (int j=len - cmd.name().length(); j >= 0; j--) w.write(" ");
60                     w.write(" - ");
61                     w.write(cmd.summary());
62                     w.write("\n");
63                 }
64                 w.write("\nFor usage details, type help [command name].\n");
65             }
66         }
67     }
68
69     public static class Ls extends Command {
70         public String name() { return "ls"; }
71         public String usage() { return "[path]"; }
72         public String summary() { return "List object entries."; }
73         public String help() { return
74             "Lists the keys in an object. Modelled after the UNIX ls command.";
75         }
76
77         public void execute(Writer w, String[] c, Env env) throws IOException {
78             if (c.length > 2) { w.write(usage()); return; }
79             String p = env.path(c.length == 1 ? "*" : c[1]);
80
81             Request.Response ret = env.send(new Request.Key(p));
82             if (!(ret instanceof Request.Key.Res)) {
83                 w.write("error: ");
84                 w.write(ret.error().getMessage());
85                 w.write("\n");
86             } else {
87                 List l = ((Request.Key.Res)ret).keys();
88                 Iterator i = l.iterator(); while (i.hasNext()) {
89                     w.write(i.next().toString());
90                     w.write("\n");
91                 }
92             }
93         }
94     }
95
96     public static class Pwd extends Command {
97         public String name() { return "pwd"; }
98         public String usage() { return ""; }
99         public String summary() { return "Path to current object."; }
100         public String help() { return "Print the path to the current object."; }
101         public void execute(Writer w, String[] c, Env env) throws IOException {
102             if (c.length != 1) { w.write(usage()); return; }
103             w.write(env.path.equals("") ? "." : env.path);
104             w.write("\n");
105         }
106     }
107
108     public static class Cd extends Command {
109         public String name() { return "cd"; }
110         public String usage() { return "[path]"; }
111         public String summary() { return "Change current object."; }
112         public String help() { return
113             "Chnages the current object that all other commands use "+
114             "as the base for running.\n Pass either a relative path "+
115             "(e.g. in .prevalent, type cd myob, now in .prevalent.myob) "+
116             "or an absolute path (e.g. cd .prevalent.myob).\n\n" +
117             "To go up one level, cd .. can be used.";
118         }
119         public void execute(Writer w, String[] c, Env env) throws IOException {
120             if (c.length > 2) w.write(usage());
121             else if (c.length == 1 || c[1].equals("") || c[1].equals(".")) env.path = "";
122             else if (c[1].equals("..")) {
123                 String n = env.path;
124                 n = n.substring(0, n.lastIndexOf('.'));
125                 env.path = n;
126             } else {
127                 String n = env.path(c[1]);
128
129                 Request.Response ret = env.send(new Request.Key(n));
130                 if (!(ret instanceof Request.Key.Res)) {
131                     w.write("error: ");
132                     w.write(ret.error().getMessage());
133                     w.write("\n");
134                 } else {
135                     List l = ((Request.Key.Res)ret).keys();
136                     if (l.size() == 0) {
137                         w.write("error: ");
138                         w.write(c[1]);
139                         w.write(": no such path\n");
140                     } else {
141                         env.path = n;
142                     }
143                 }
144             }
145         }
146     }
147
148     public static class Rm extends Command {
149         public String name() { return "rm"; }
150         public String usage() { return "[options] [path]"; }
151         public String summary() { return "Removes objects."; }
152         public String help() { return "Removes objects."; } // FIXME
153         public void execute(Writer w, String[] c, Env env) throws IOException {
154             if (c.length == 1) { w.write(usage()); }
155
156             Request.Key[] r = new Request.Key[c.length - 1];
157             for (int i=0; i < r.length; i++) r[i] = new Request.RemoveKey(env.path(c[i + 1]));
158
159             Request.Response ret = env.send(new Request.Composite(r, false));
160             if (!(ret instanceof Request.Composite.Res)) {
161                 w.write("error: ");
162                 w.write(ret.error().getMessage());
163                 w.write("\n");
164             } else {
165                 Request.Response[] res = ((Request.Composite.Res)ret).responses();
166                 for (int i=0; i < res.length; i++) {
167                     if (res[i] instanceof Request.RemoveKey.Res) {
168                         boolean rm = ((Request.RemoveKey.Res)res[i]).removed();
169                         if (!rm) {
170                             w.write("error: cannot remove '");
171                             w.write(c[i + 1]);
172                             w.write("': no such key\n");
173                         }
174                     } else {
175                         w.write("error: cannot remove '");
176                         w.write(c[i + 1]);
177                         w.write("': ");
178                         w.write(res[i].error().getMessage());
179                         w.write("\n");
180                     }
181                 }
182             }
183         }
184     }
185
186     public static class Set extends Command {
187         public String name() { return "set"; }
188         public String usage() { return "[name] [object]"; }
189         public String summary() { return "Sets ."; }
190         public String help() { return "Removes objects."; } // FIXME
191
192         public void execute(Writer w, String[] c, Env env) throws IOException {
193             if (c.length < 3) { w.write(usage()); }
194
195             String m = c[1];
196             String s = "return (";
197             for (int i=2; i < c.length; i++) s += c[i];
198             s += ");";
199
200             JS js;
201             try { js = JS.fromReader("input", 0, new StringReader(s)); }
202             catch (IOException e) {
203                 w.write("error: ");
204                 w.write(e.getMessage());
205                 w.write("\n");
206                 return;
207             }
208
209             Request.Response ret = env.send(new Request.SetKey(env.path, m, js));
210         }
211     }
212
213 }