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