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