6 import java.util.regex.*;
7 import javax.servlet.*;
8 import javax.servlet.http.*;
10 import org.ibex.util.*;
11 import org.ibex.util.Collections;
14 import org.prevayler.*;
18 public static void main(String[] args) throws Exception {
19 if (args.length == 0 || args.length > 2|| !args[0].startsWith("http://")) {
22 Shell shell = new Shell(new URL(args[0]));
24 if (args.length == 2) {
25 System.out.println(shell.execute(args[1]));
27 shell.listen(new InputStreamReader(System.in), new OutputStreamWriter(System.out));
31 private static void printUsage() {
32 System.out.println("Usage: xish url [command]");
38 /** Current JS path using '.' as a seperator. */
39 private String pwd = ".";
41 /** Create a new Shell using the given url for the server. */
42 public Shell(URL url) { server = url; }
44 public void listen(Reader r, Writer w) throws IOException {
45 LineNumberReader in = new LineNumberReader(r);
46 PrintWriter out = new PrintWriter(w);
48 out.println("Ibex xt shell. Type help or exit.");
54 while ((line = in.readLine()) != null) {
55 if (line.length() > 0) {
56 if (line.startsWith("exit")) return;
57 if (line.charAt(line.length() - 1) == '\\') {
58 buffer += line.substring(0, line.length() - 1);
60 out.flush(); continue;
66 if (buffer.length() > 0) {
77 public String execute(String cmd) throws IOException {
78 StringWriter s = new StringWriter();
83 public void execute(String cmd, Writer w) throws IOException {
84 if (cmd == null || cmd.length() == 0) return;
85 String[] c = cmd.split(" ");
89 if (c.length > 2) { w.write("usage: ls [path]\n"); return; }
91 String matcher = ".*";
93 int pos = c[1].lastIndexOf('/');
94 path += c[1].substring(0, pos);
95 path.replaceAll("/", "\\.");
96 if (pos + 1 < c[1].length()) {
97 matcher = c[1].substring(pos + 1);
98 matcher.replaceAll("\\.", "\\.");
99 matcher.replaceAll("\\*", ".*");
103 Object ret = send(new KeyRequest(path, matcher));
105 error(w, "returned object is null"); return;
106 } else if (ret instanceof JSExn) {
107 error(w, (JSExn)ret); return;
108 } else if (ret instanceof List) {
109 List l = (List)ret; Collections.sort(l);
110 Iterator i = l.iterator(); while (i.hasNext()) {
112 w.write(i.next().toString());
117 error(w, "returned object of unknown type: "+ret.getClass().getName());return;
120 w.write(pwd.replace('.', '/'));
123 throw new Error("not yet implemented");
125 w.write("Available commands:\n");
126 w.write(" ls - list entries in current object\n");
127 w.write(" pwd - path of current object\n");
128 w.write(" help - this message\n");
129 w.write(" exit - close xt shell\n");
133 public void error(Writer w, String s) throws IOException {
134 w.write("Unexpected error: ");
139 public void error(Writer w, JSExn e) throws IOException {
140 w.write("\nerror: ");
141 w.write(e.getMessage());
145 public Object send(Request request) throws IOException {
146 URLConnection c = server.openConnection();
147 ((HttpURLConnection)c).setRequestMethod("POST");
151 ObjectOutputStream out = new ObjectOutputStream(c.getOutputStream());
152 out.writeObject(request);
156 return new ObjectInputStream(c.getInputStream()).readObject();
157 } catch (ClassNotFoundException e) {
159 throw new IOException("unexpected ClassNotFoundException");
163 public static abstract class Request implements Serializable {
164 public abstract Object process(JSScope root) throws JSExn;
167 public static class KeyRequest extends Request {
168 private String path, matcher;
169 public KeyRequest() {}
170 public KeyRequest(String path, String matcher) {
171 this.path = path; this.matcher = matcher;
174 /** Returns a List. */
175 public Object process(JSScope root) throws JSExn {
176 String p = path == null ? "" : path.replaceAll("\\.+", "\\.");
177 if (p.length() > 0 && p.charAt(0) == '.') p = p.substring(1);
178 if (p.length() > 0 && p.charAt(p.length() - 1) == '.') p = p.substring(0, p.length() - 1);
179 System.out.println("searching path '"+p+"' for pattern '"+matcher+"'");
181 Object o = p.equals("") ? root : root.get(p);
182 if (o == null || o instanceof JSDate ||
183 o instanceof JSArray ||
184 !(o instanceof JS)) {
185 System.out.println("hit bad object: "+o+", class="+
186 (o == null ? null : o.getClass().getName()));
187 throw new JSExn("path /" + p + " does not exist");
189 Pattern pat = Pattern.compile(matcher);
190 List keys = new ArrayList();
192 Iterator i = ((JS)o).keys().iterator(); while(i.hasNext()) {
193 String k = i.next().toString();
194 if (pat.matcher(k).matches()) keys.add(k);
202 public static class ExecRequest extends Request {
204 public ExecRequest() {}
205 public ExecRequest(JS exec) { this.exec = exec; }
206 public ExecRequest(String source) throws IOException, JSExn {
207 this(new StringReader(source));
209 public ExecRequest(Reader source) throws IOException, JSExn {
210 exec = JS.fromReader("xsh", 0, source);
213 /** Returns the result of <tt>JS.eval()</tt>. */
214 public Object process(JSScope root) throws JSExn {
215 return JS.eval(JS.cloneWithNewParentScope(exec, root));