001    package org.crsh.shell.impl.remoting;
002    
003    import org.crsh.cmdline.CommandCompletion;
004    import org.crsh.shell.Shell;
005    import org.crsh.shell.ShellProcess;
006    import org.crsh.util.CloseableList;
007    
008    import java.io.Closeable;
009    import java.io.IOException;
010    import java.io.InputStream;
011    import java.io.ObjectInputStream;
012    import java.io.ObjectOutputStream;
013    import java.io.OutputStream;
014    
015    /** @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a> */
016    public class ClientAutomaton implements Runnable {
017    
018      /** . */
019      final Shell shell;
020    
021      /** . */
022      final ObjectOutputStream out;
023    
024      /** . */
025      final ObjectInputStream in;
026    
027      /** . */
028      ClientProcessContext current;
029    
030      /** . */
031      final CloseableList listeners;
032    
033      public ClientAutomaton(ObjectOutputStream out, ObjectInputStream in, Shell shell) {
034        CloseableList listeners = new CloseableList();
035        listeners.add(in);
036        listeners.add(out);
037    
038        //
039        this.in = in;
040        this.out = out;
041        this.shell = shell;
042        this.listeners = listeners;
043      }
044    
045      public ClientAutomaton(InputStream in,OutputStream out, Shell shell) throws IOException {
046        this(new ObjectOutputStream(out), new ObjectInputStream(in), shell);
047      }
048    
049      public ClientAutomaton addCloseListener(Closeable closeable) {
050        listeners.add(closeable);
051        return this;
052      }
053    
054      public void run() {
055        try {
056          while (!listeners.isClosed()) {
057            ClientMessage msg = (ClientMessage)in.readObject();
058            switch (msg) {
059              case GET_WELCOME:
060                String welcome = shell.getWelcome();
061                out.writeObject(welcome);
062                out.flush();
063                break;
064              case GET_PROMPT:
065                String prompt = shell.getPrompt();
066                out.writeObject(prompt);
067                out.flush();
068                break;
069              case GET_COMPLETION:
070                String prefix = (String)in.readObject();
071                CommandCompletion completion = shell.complete(prefix);
072                out.writeObject(completion);
073                out.flush();
074                break;
075              case EXECUTE:
076                String line = (String)in.readObject();
077                ShellProcess process = shell.createProcess(line);
078                current = new ClientProcessContext(this, process);
079                process.execute(current);
080                break;
081              case CANCEL:
082                if (current != null) {
083                  current.process.cancel();
084                }
085                break;
086              case CLOSE:
087                close();
088                break;
089            }
090          }
091        }
092        catch (Exception e) {
093    //      e.printStackTrace();
094          //
095        }
096      }
097    
098      void close() {
099        listeners.close();
100      }
101    }