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.setEcho(echo);
039 processor.term.write(msg);
040 }
041 catch (IOException e) {
042 return null;
043 }
044 boolean done = false;
045 while (true) {
046 synchronized (processor.lock) {
047 switch (processor.status) {
048 case CLOSED:
049 case CANCELLING:
050 return null;
051 case PROCESSING:
052 if (processor.queue.size() > 0) {
053 TermEvent event = processor.queue.removeFirst();
054 if (event instanceof TermEvent.ReadLine) {
055 return ((TermEvent.ReadLine)event).getLine().toString();
056 }
057 }
058 break;
059 default:
060 throw new AssertionError("Does not make sense " + processor.status);
061 }
062 }
063 if (done) {
064 return null;
065 } else {
066 done = true;
067 processor.waitingEvent = true;
068 try {
069 processor.readTerm();
070 }
071 finally {
072 processor.waitingEvent = false;
073 }
074 }
075 }
076 }
077
078 public void end(ShellResponse response) {
079 Runnable runnable;
080 ProcessContext context;
081 Status status;
082 synchronized (processor.lock) {
083
084 //
085 processor.current = null;
086 switch (processor.status) {
087 case PROCESSING:
088 if (response instanceof ShellResponse.Close) {
089 runnable = processor.CLOSE;
090 processor.status = Status.CLOSED;
091 } else if (response instanceof ShellResponse.Cancelled) {
092 runnable = Processor.NOOP;
093 processor.status = Status.AVAILABLE;
094 } else {
095 final String display = response.getText();
096 runnable = new Runnable() {
097 public void run() {
098 processor.write(display);
099 }
100 };
101 processor.status = Status.AVAILABLE;
102 }
103 break;
104 case CANCELLING:
105 runnable = Processor.NOOP;
106 processor.status = Status.AVAILABLE;
107 break;
108 default:
109 throw new AssertionError("Does not make sense " + processor.status);
110 }
111
112 // Do we have a next process to execute ?
113 context = processor.peekProcess();
114 status = processor.status;
115 }
116
117 //
118 runnable.run();
119
120 //
121 if (context != null) {
122 context.run();
123 } else if (status == Status.AVAILABLE) {
124 processor.writePrompt();
125 }
126 }
127 }