001    package org.crsh.term.processor;
002    
003    import org.crsh.shell.ShellProcess;
004    import org.crsh.shell.ShellProcessContext;
005    import org.crsh.shell.ShellResponse;
006    import org.crsh.term.TermEvent;
007    
008    import java.io.IOException;
009    
010    /** @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a> */
011    class ProcessContext implements ShellProcessContext, Runnable {
012    
013      /** . */
014      final Processor processor;
015    
016      /** . */
017      final ShellProcess process;
018    
019      ProcessContext(Processor processor, ShellProcess process) {
020        this.process = process;
021        this.processor = processor;
022      }
023    
024      public void run() {
025        process.execute(this);
026      }
027    
028      public int getWidth() {
029        return processor.term.getWidth();
030      }
031    
032      public String getProperty(String name) {
033        return processor.term.getProperty(name);
034      }
035    
036      public String readLine(String msg, boolean echo) {
037        try {
038          processor.term.write(msg);
039        }
040        catch (IOException e) {
041          return null;
042        }
043        boolean done = false;
044        while (true) {
045          synchronized (processor.lock) {
046            switch (processor.status) {
047              case CLOSED:
048              case CANCELLING:
049                return null;
050              case PROCESSING:
051                if (processor.queue.size() > 0) {
052                  TermEvent event = processor.queue.removeFirst();
053                  if (event instanceof TermEvent.ReadLine) {
054                    return ((TermEvent.ReadLine)event).getLine().toString();
055                  }
056                }
057                break;
058              default:
059                throw new AssertionError("Does not make sense " + processor.status);
060            }
061          }
062          if (done) {
063            return null;
064          } else {
065            done = true;
066            processor.waitingEvent = true;
067            try {
068              processor.term.setEcho(echo);
069              processor.readTerm();
070              processor.term.write("\r\n");
071            }
072            catch (IOException e) {
073              processor.log.error("Error when readline line");
074            }
075            finally {
076              processor.waitingEvent = false;
077              processor.term.setEcho(true);
078            }
079          }
080        }
081      }
082    
083      public void end(ShellResponse response) {
084        Runnable runnable;
085        ProcessContext context;
086        Status status;
087        synchronized (processor.lock) {
088    
089          //
090          processor.current = null;
091          switch (processor.status) {
092            case PROCESSING:
093              if (response instanceof ShellResponse.Close) {
094                runnable = processor.CLOSE;
095                processor.status = Status.CLOSED;
096              } else if (response instanceof ShellResponse.Cancelled) {
097                runnable = Processor.NOOP;
098                processor.status = Status.AVAILABLE;
099              } else {
100                final String display = response.getText();
101                runnable = new Runnable() {
102                  public void run() {
103                    processor.write(display);
104                  }
105                };
106                processor.status = Status.AVAILABLE;
107              }
108              break;
109            case CANCELLING:
110              runnable = Processor.NOOP;
111              processor.status = Status.AVAILABLE;
112              break;
113            default:
114              throw new AssertionError("Does not make sense " + processor.status);
115          }
116    
117          // Do we have a next process to execute ?
118          context = processor.peekProcess();
119          status = processor.status;
120        }
121    
122        //
123        runnable.run();
124    
125        //
126        if (context != null) {
127          context.run();
128        } else if (status == Status.AVAILABLE) {
129          processor.writePrompt();
130        }
131      }
132    }