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.Screenable;
008    import org.crsh.text.Style;
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      @Override
097      public Appendable append(char c) throws IOException {
098        return append(Character.toString(c));
099      }
100    
101      @Override
102      public Appendable append(CharSequence s) throws IOException {
103        return append(s, 0, s.length());
104      }
105    
106      @Override
107      public Appendable append(CharSequence csq, int start, int end) throws IOException {
108        while (start < end) {
109          // This is not perfect but it will be OK for now
110          // ideally we should reuse the IO / ConsoleTerm stuff
111          // but for now we don't have the time to do it properly
112          char c = csq.charAt(start++);
113          if (c == '\r') {
114            //
115          } else if (c == '\n') {
116            out.print("\r\n");
117          } else {
118            out.print(c);
119          }
120        }
121        return this;
122      }
123    
124      @Override
125      public Screenable append(Style style) throws IOException {
126        return null;
127      }
128    
129      @Override
130      public Screenable cls() throws IOException {
131        return null;
132      }
133    
134      public void flush() throws IOException {
135        out.flush();
136      }
137    
138      public void end(ShellResponse response) {
139        this.response = response;
140        this.latch.countDown();
141      }
142    
143      ShellResponse getResponse() {
144        try {
145          latch.await();
146          return response;
147        }
148        catch (InterruptedException e) {
149          throw new RuntimeException(e);
150        }
151      }
152    
153    }