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    import java.util.concurrent.Callable;
015    import java.util.concurrent.Future;
016    import java.util.concurrent.FutureTask;
017    
018    /** @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a> */
019    public class ClientAutomaton implements Runnable {
020    
021      /** . */
022      final Shell shell;
023    
024      /** . */
025      final ObjectOutputStream out;
026    
027      /** . */
028      final ObjectInputStream in;
029    
030      /** . */
031      ClientProcessContext current;
032    
033      /** . */
034      final CloseableList listeners;
035    
036      /** . */
037      Integer width;
038    
039      public ClientAutomaton(ObjectOutputStream out, ObjectInputStream in, Shell shell) {
040        CloseableList listeners = new CloseableList();
041        listeners.add(in);
042        listeners.add(out);
043    
044        //
045        this.in = in;
046        this.out = out;
047        this.shell = shell;
048        this.listeners = listeners;
049      }
050    
051      public ClientAutomaton(InputStream in,OutputStream out, Shell shell) throws IOException {
052        this(new ObjectOutputStream(out), new ObjectInputStream(in), shell);
053      }
054    
055      public ClientAutomaton addCloseListener(Closeable closeable) {
056        listeners.add(closeable);
057        return this;
058      }
059    
060      public void run() {
061        try {
062          while (!listeners.isClosed()) {
063            ClientMessage msg = (ClientMessage)in.readObject();
064            switch (msg) {
065              case GET_WELCOME:
066                String welcome = shell.getWelcome();
067                out.writeObject(welcome);
068                out.flush();
069                break;
070              case GET_PROMPT:
071                String prompt = shell.getPrompt();
072                out.writeObject(prompt);
073                out.flush();
074                break;
075              case GET_COMPLETION:
076                String prefix = (String)in.readObject();
077                CommandCompletion completion = shell.complete(prefix);
078                out.writeObject(completion);
079                out.flush();
080                break;
081              case EXECUTE:
082                width = (Integer) in.readObject();
083                String line = (String)in.readObject();
084                ShellProcess process = shell.createProcess(line);
085                current = new ClientProcessContext(this, process);
086                process.execute(current);
087                break;
088              case CANCEL:
089                if (current != null) {
090                  current.process.cancel();
091                }
092                break;
093              case CLOSE:
094                close();
095                break;
096            }
097          }
098        }
099        catch (Exception e) {
100    //      e.printStackTrace();
101          //
102        }
103      }
104    
105      void close() {
106        listeners.close();
107      }
108    
109      public int getWidth() {
110        return width;
111      }
112      
113    }