1 package org.ibex.xt.shell;
7 import org.ibex.util.*;
11 public static void main(String[] args) throws Exception {
12 if (args.length == 0 || args.length > 2|| !args[0].startsWith("http://")) {
15 Shell shell = new Shell(new URL(args[0]));
17 if (args.length == 2) {
20 shell.listen(new InputStreamReader(System.in), new OutputStreamWriter(System.out));
24 private static void printUsage() {
25 System.out.println("Usage: xish url [command]");
29 /** Supported commands. */
30 private Command[] commands;
33 private final JS root;
35 /** Current JS context for the shell. */
38 /** Current path to <tt>scope</tt> in <tt>root</tt>. */
39 private Object[] path;
41 /** Returns the object represented by the given path,
42 * ignoring the current shell path context.*/
43 public Object getFromPath(Object[] path) throws BadPathException, JSExn {
44 if (path.length == 0) return root;
46 if (root instanceof JSRemote) {
47 // JSRemote will automatically process its keys for '.' seperators
48 StringBuffer sb = new StringBuffer(path[0].toString());
49 for (int i=1; i < path.length; i++) {
50 sb.append('.'); sb.append(path[i].toString());
52 return root.get(sb.toString());
55 for (int i=0; i < path.length - 1; i++) {
56 Object o = cur.get(path[i]);
57 if (o == null || !(o instanceof JS)) throw new Shell.BadPathException();
60 return cur.get(path[path.length - 1]);
64 public void transaction(JS t) {
65 if (root instanceof JSRemote) {
66 ((JSRemote)root).transaction(
67 JS.cloneWithNewParentScope(t, new JSScope(null)));
69 // FIXME JS.eval(JS.cloneWithNewParentScope(t, root));
73 /** Set the current path of the shell, modifiying the result of getScope(). */
74 public void setPath(Object[] s) throws BadPathException {
76 if (s == null) s = new Object[0];
77 for (int i=0; i < s.length; i++) {
79 try { o = cur.get(s[i]); } catch (JSExn e) { throw new BadPathException(); }
80 if (o == null || !(o instanceof JS)) throw new BadPathException();
87 /** Returns the current path of the shell. */
88 public Object[] getPath() { return path; }
90 /** Returns String represntation of path, using '/' as a seperator. */
91 public String getPathAsString() {
92 if (path.length == 0) return "/";
93 StringBuffer sb = new StringBuffer();
94 for (int i=0; i < path.length; i++) {
95 sb.append('/'); sb.append(path[i].toString());
100 /** Returns the context matching the current path. */
101 public JS getScope() { return scope; }
103 /** Returns the context matching the current path. */
104 public JS getRootScope() { return root; }
106 /** Returns all supported commands. */
107 public Command[] getCommands() { return commands; }
109 /** Returns the command matching the given name. */
110 public Command getCommand(String name) {
111 for (int i=0; i < commands.length; i++)
112 if (commands[i].name().equals(name)) return commands[i];
116 /** Create a new Shell using the given url for the server. */
117 public Shell(URL url) {
118 root = scope = new JSRemote(url);
119 path = new String[0];
120 commands = new Command[] {
121 new Command.Ls(this),
122 new Command.Pwd(this),
123 new Command.Cd(this),
124 new Command.Rm(this),
125 new Command.Help(this)
129 public void listen(Reader r, Writer w) throws IOException {
130 LineNumberReader in = new LineNumberReader(r);
131 PrintWriter out = new PrintWriter(w);
133 out.println("ibex xt shell: type help or exit");
134 out.print("xt:"); out.print(getPathAsString()); out.print("# ");
139 int countBraceOpen = 0, countBraceClose = 0;
140 int countBracketOpen = 0, countBracketClose = 0;
141 int countSQBracketOpen = 0, countSQBracketClose = 0;
142 while ((line = in.readLine()) != null) {
143 if (line.length() > 0) {
144 if (line.startsWith("exit")) return;
146 for (int i=0; i < line.length(); i++) {
147 switch (line.charAt(i)) {
148 case '{': countBraceOpen++; break;
149 case '}': countBraceClose++; break;
150 case '(': countBracketOpen++; break;
151 case ')': countBracketClose++; break;
152 case '[': countSQBracketOpen++; break;
153 case ']': countSQBracketClose++; break;
157 boolean nonendchar = line.charAt(line.length() - 1) == '\\';
158 if (nonendchar) line = line.substring(0, line.length() - 1);
162 countBracketOpen != countBracketClose ||
163 countBraceOpen != countBraceClose ||
164 countSQBracketOpen != countSQBracketClose) {
166 out.flush(); continue;
170 if (buffer.length() > 0) {
171 String[] c = buffer.split(" ");
172 Command cmd = getCommand(c[0]);
176 w.write(": command not found\n");
177 } else cmd.execute(out, c);
181 out.print("xt:"); out.print(getPathAsString()); out.print("# ");
186 public static class BadPathException extends Exception {
187 public BadPathException() {}
188 public BadPathException(String msg) { super(msg); }