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 NoSuchPathException, 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.NoSuchPathException();
60 return cur.get(path[path.length - 1]);
64 /** Set the current path of the shell, modifiying the result of getScope(). */
65 public void setPath(Object[] s) throws NoSuchPathException {
67 if (s == null) s = new Object[0];
68 for (int i=0; i < s.length; i++) {
70 try { o = cur.get(s[i]); } catch (JSExn e) { throw new NoSuchPathException(); }
71 if (o == null || !(o instanceof JS)) throw new NoSuchPathException();
78 /** Returns the current path of the shell. */
79 public Object[] getPath() { return path; }
81 /** Returns String represntation of path, using '/' as a seperator. */
82 public String getPathAsString() {
83 if (path.length == 0) return "/";
84 StringBuffer sb = new StringBuffer();
85 for (int i=0; i < path.length; i++) {
86 sb.append('/'); sb.append(path[i].toString());
91 /** Returns the context matching the current path. */
92 public JS getScope() { return scope; }
94 /** Returns the context matching the current path. */
95 public JS getRootScope() { return root; }
97 /** Returns all supported commands. */
98 public Command[] getCommands() { return commands; }
100 /** Returns the command matching the given name. */
101 public Command getCommand(String name) {
102 for (int i=0; i < commands.length; i++)
103 if (commands[i].name().equals(name)) return commands[i];
107 /** Create a new Shell using the given url for the server. */
108 public Shell(URL url) {
109 root = scope = new JSRemote(url);
110 path = new String[0];
111 commands = new Command[] {
112 new Command.Ls(this),
113 new Command.Pwd(this),
114 new Command.Cd(this),
115 new Command.Rm(this),
116 new Command.Help(this)
120 public void listen(Reader r, Writer w) throws IOException {
121 LineNumberReader in = new LineNumberReader(r);
122 PrintWriter out = new PrintWriter(w);
124 out.println("ibex xt shell: type help or exit");
125 out.print("xt:"); out.print(getPathAsString()); out.print("# ");
130 int countBraceOpen = 0, countBraceClose = 0;
131 int countBracketOpen = 0, countBracketClose = 0;
132 int countSQBracketOpen = 0, countSQBracketClose = 0;
133 while ((line = in.readLine()) != null) {
134 if (line.length() > 0) {
135 if (line.startsWith("exit")) return;
137 for (int i=0; i < line.length(); i++) {
138 switch (line.charAt(i)) {
139 case '{': countBraceOpen++; break;
140 case '}': countBraceClose++; break;
141 case '(': countBracketOpen++; break;
142 case ')': countBracketClose++; break;
143 case '[': countSQBracketOpen++; break;
144 case ']': countSQBracketClose++; break;
148 boolean nonendchar = line.charAt(line.length() - 1) == '\\';
149 if (nonendchar) line = line.substring(0, line.length() - 1);
153 countBracketOpen != countBracketClose ||
154 countBraceOpen != countBraceClose ||
155 countSQBracketOpen != countSQBracketClose) {
157 out.flush(); continue;
161 if (buffer.length() > 0) {
162 String[] c = buffer.split(" ");
163 Command cmd = getCommand(c[0]);
167 w.write(": command not found\n");
168 } else cmd.execute(out, c);
172 out.print("xt:"); out.print(getPathAsString()); out.print("# ");
177 public static class NoSuchPathException extends Exception {}