001    package org.crsh.ssh.term.inline;
002    
003    import org.crsh.shell.ShellProcess;
004    import org.crsh.shell.ShellProcessContext;
005    import org.crsh.shell.ShellResponse;
006    import org.crsh.ssh.term.SSHContext;
007    import org.crsh.text.Chunk;
008    import org.crsh.text.Text;
009    
010    import java.io.IOException;
011    import java.io.PrintStream;
012    import java.util.concurrent.CountDownLatch;
013    
014    /** ShellProcessContext for SSH inline commands */
015    public class SSHInlineShellProcessContext implements ShellProcessContext {
016    
017      /** . */
018      private static final String MSG = "Cannot determine tty width : you should force pseudo-tty allocation (-t option)";
019    
020      /** . */
021      private boolean msgDone;
022    
023      /** . */
024      private ShellResponse response;
025    
026      /** . */
027      private final CountDownLatch latch;
028    
029      /** . */
030      private final SSHContext context;
031    
032      /** . */
033      private final ShellProcess process;
034    
035      /** . */
036      private final PrintStream out;
037    
038      /** . */
039      private final PrintStream err;
040    
041      SSHInlineShellProcessContext(SSHContext context, ShellProcess process, PrintStream out, PrintStream err) {
042        this.out = out;
043        this.context = context;
044        this.process = process;
045        this.latch = new CountDownLatch(1);
046        this.response = null;
047        this.err = err;
048        this.msgDone = false;
049      }
050    
051      public SSHInlineShellProcessContext execute() {
052        process.execute(this);
053        return this;
054      }
055    
056      public boolean takeAlternateBuffer() {
057        return false;
058      }
059    
060      public boolean releaseAlternateBuffer() {
061        return false;
062      }
063    
064      public int getWidth() {
065        int width = context.getWidth();
066        if (width == -1) {
067          if (!msgDone) {
068            msgDone = true;
069            out.print(MSG);
070            out.flush();
071          }
072        }
073        return width;
074      }
075    
076      public int getHeight() {
077        int height = context.getHeight();
078        if (height == -1) {
079          if (!msgDone) {
080            msgDone = true;
081            out.print(MSG);
082            out.flush();
083            }
084        }
085        return height;
086      }
087    
088      public String getProperty(String name) {
089        return context.getProperty(name);
090      }
091    
092      public String readLine(String msg, boolean echo) {
093        return null;
094      }
095    
096      public void write(Chunk element) throws IOException {
097        if (element instanceof Text) {
098          CharSequence seq = ((Text)element).getText();
099          int length = seq.length();
100          if (length > 0) {
101            for (int i = 0;i < length;i++) {
102              // This is not perfect but it will be OK for now
103              // ideally we should reuse the IO / ConsoleTerm stuff
104              // but for now we don't have the time to do it properly
105              char c = seq.charAt(i);
106              if (c == '\r') {
107                //
108              } else if (c == '\n') {
109                out.print("\r\n");
110              } else {
111                out.print(c);
112              }
113            }
114          }
115        }
116      }
117    
118      public void flush() throws IOException {
119        out.flush();
120      }
121    
122      public void end(ShellResponse response) {
123        this.response = response;
124        this.latch.countDown();
125      }
126    
127      ShellResponse getResponse() {
128        try {
129          latch.await();
130          return response;
131        }
132        catch (InterruptedException e) {
133          throw new RuntimeException(e);
134        }
135      }
136    
137    }