1 package gnu.kawa.servlet; 2 import gnu.text.*; 3 import gnu.mapping.*; 4 import gnu.expr.*; 5 import gnu.lists.PrintConsumer; 6 import java.io.*; 7 import gnu.xml.*; 8 9 10 11 public class ReplSession extends Writer 12 { 13 Language language; 14 Environment penvironment; 15 QueueReader qreader; 16 InPort in_p; 17 OutBufferWriter err_p; 18 OutBufferWriter out_p; 19 OutBufferWriter prompt_p; 20 Future thread; 21 22 StringBuffer outBuffer = new StringBuffer (); 23 boolean outAvailable; 24 25 void append1 (char c) 26 { 27 if (c == '\r' || c == '\n') 28 outBuffer.append("<br/>"); 29 else 30 outBuffer.append(c); 31 } 32 33 public void write (int c) 34 { 35 synchronized (this) 36 { 37 append1((char) c); 38 } 39 } 40 41 public void write (char[] cbuf, int off, int len) 42 { 43 synchronized (this) 44 { 45 for (int i = 0; i < len; i++) 46 append1(cbuf[off+i]); 47 } 48 } 49 50 public void write (String str, int off, int len) 51 { 52 synchronized (this) 53 { 54 for (int i = 0; i < len; i++) 55 append1(str.charAt(off+i)); 56 } 57 } 58 59 public void flush () 60 { 61 synchronized (this) 62 { 63 if (outBuffer.length() > 0) 64 outAvailable = true; 65 notify(); 66 } 67 } 68 69 public void close () 70 { 71 flush(); 72 } 73 74 String grabOutput () 75 { 76 synchronized (this) 77 { 78 return grabOutputRaw(); 79 } 80 } 81 82 String waitOutput () 83 { 84 synchronized (this) 85 { 86 if (! outAvailable) 87 { 88 try 89 { 90 wait(30000); 91 } 92 catch (Throwable ex) 93 { 94 ex.printStackTrace(); 95 } 96 } 97 String out = grabOutputRaw(); 98 return out; 99 } 100 } 101 102 String grabOutputRaw () 103 { 104 String result = outBuffer.toString(); 105 outBuffer.setLength(0); 106 outAvailable = false; 107 return result; 109 } 110 111 public ReplSession () 112 { 113 this(kawa.standard.Scheme.getInstance()); 114 } 116 117 public ReplSession (Language language) 118 { 119 if (Language.getDefaultLanguage() == null) 120 Language.setDefaults(language); 121 penvironment = Environment.getCurrent(); 122 qreader = new QueueReader(); 123 124 out_p = new OutBufferWriter(this, 'O', "<stdout>"); 125 err_p = new OutBufferWriter(this, 'E', "<stderr>"); 126 prompt_p = new OutBufferWriter(this, 'P', "<prompt>"); 127 in_p = new MyTtyInPort(qreader, "<stdin>", out_p, this); 128 129 thread = new Future (new kawa.repl(language), 130 penvironment, in_p, out_p, err_p); 131 thread.start(); 132 } 133 134 void appendInputLine (String line) 135 { 136 qreader.append(line); 137 qreader.append('\n'); 138 } 139 140 void appendInput (String line) 141 { 142 qreader.append(line); 143 } 144 } 145 146 class MyTtyInPort extends TtyInPort 147 { 148 ReplSession session; 149 OutBufferWriter prompt_p; 150 public MyTtyInPort (Reader in, String name, OutPort tie, 151 ReplSession session) 152 { 153 super(in, name, tie); 154 this.session = session; 155 this.prompt_p = session.prompt_p; 156 } 157 158 int pcount; 159 160 public void lineStart (boolean revisited) throws java.io.IOException 161 { 162 if (! revisited && prompter != null) 163 { 164 try 165 { 166 tie.freshLine(); 167 Object prompt = prompter.apply1(this); 168 if (prompt != null) 169 { 170 String string = prompt.toString(); 171 if (string != null && string.length() > 0) 172 { 173 synchronized (session) 174 { 175 session.out_p.flushToSessionBuffer(); 176 session.outBuffer.append("<div class=\"interaction\"><span std=\"prompt\">"); 177 prompt_p.write(string); 178 prompt_p.flushToSessionBuffer(); 179 session.outBuffer.append("</span><input std='input' value='' onchange='enterLine(this);'/></div>"); 180 session.flush(); 181 } 182 tie.clearBuffer(); 183 promptEmitted = true; 184 } 185 } 186 } 187 catch (Throwable ex) 188 { throw new java.io.IOException ("Error when evaluating prompt:" 189 + ex); } 190 } 191 } 192 } 193 194 class OutBufferWriter extends OutPort 195 { 196 ReplSession session; 197 202 char kind; 203 int nesting = 0; 204 XMLPrinter xout; 205 206 public OutBufferWriter (ReplSession session, char kind, String name) 207 { 208 super(session, false, true, name); 209 this.session = session; 210 this.kind = kind; 211 xout = new XMLPrinter(bout, true); 212 out = xout; 213 } 214 215 public void write (int c) 216 { 217 xout.write(c); 218 } 219 220 221 public void write(CharSequence str, int start, int length) 222 223 225 { 226 xout.write(str, start, length); 227 } 228 229 public void write (String str) 230 { 231 int len = str.length(); 232 xout.write(str, 0, len); 233 } 234 235 public void beginGroup (Object type) 236 { 237 nesting++; 238 xout.beginGroup(type); 239 } 240 241 public void endGroup () 242 { 243 nesting--; 244 xout.endGroup(); 245 } 246 247 public void beginAttribute (Object attrType) 248 { 249 xout.beginAttribute(attrType); 250 } 251 252 public void endAttribute() 253 { 254 xout.endAttribute(); 255 } 256 257 public void println () 258 { 259 bout.write('\n'); 260 flush(); 261 } 262 263 final void flushToSessionBuffer () throws java.io.IOException 264 { 265 bout.forcePrettyOutput(); 266 } 267 268 public void flush () 269 { 270 if (nesting > 0) 271 return; 272 synchronized (session) 273 { 274 if (kind == 'E') 275 session.outBuffer.append("<span std=\"error\">"); 276 try 277 { 278 flushToSessionBuffer(); 279 } 280 catch (IOException ex) 281 { 282 throw new RuntimeException (ex.toString()); 283 } 284 if (kind == 'E') 285 session.outBuffer.append("</span>"); 286 session.flush(); 287 } 288 } 289 } 290 | Popular Tags |