001    /*
002     * Copyright (C) 2012 eXo Platform SAS.
003     *
004     * This is free software; you can redistribute it and/or modify it
005     * under the terms of the GNU Lesser General Public License as
006     * published by the Free Software Foundation; either version 2.1 of
007     * the License, or (at your option) any later version.
008     *
009     * This software is distributed in the hope that it will be useful,
010     * but WITHOUT ANY WARRANTY; without even the implied warranty of
011     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012     * Lesser General Public License for more details.
013     *
014     * You should have received a copy of the GNU Lesser General Public
015     * License along with this software; if not, write to the Free
016     * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
017     * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
018     */
019    
020    package org.crsh.shell.impl.remoting;
021    
022    import org.crsh.shell.ShellProcess;
023    import org.crsh.shell.ShellProcessContext;
024    import org.crsh.shell.ShellResponse;
025    import org.crsh.text.Chunk;
026    
027    import java.io.IOException;
028    import java.util.ArrayList;
029    
030    class ClientProcessContext implements ShellProcessContext {
031    
032      /** . */
033      final ClientAutomaton client;
034    
035      /** . */
036      final ShellProcess process;
037    
038      /** . */
039      final ArrayList<Chunk> buffer;
040    
041      ClientProcessContext(ClientAutomaton client, ShellProcess process) {
042        this.client = client;
043        this.process = process;
044        this.buffer = new ArrayList<Chunk>(1000);
045      }
046    
047      /**
048       * Ensure we have a recent size, the size is considered as recent if it's younger than 2 second, otherwise
049       * send a get size message.
050       */
051      private void ensureSize() {
052        if (System.currentTimeMillis() - client.last > 2000) {
053          synchronized (this) {
054            try {
055              client.out.writeObject(ServerMessage.GET_SIZE);
056              client.out.flush();
057            }
058            catch (Exception e) {
059              //
060            }
061          }
062        }
063      }
064    
065      public int getWidth() {
066        ensureSize();
067        return client.getWidth();
068      }
069    
070      public int getHeight() {
071        ensureSize();
072        return client.getHeight();
073      }
074    
075      public boolean takeAlternateBuffer() {
076        try {
077          client.out.writeObject(ServerMessage.USE_ALTERNATE_BUFFER);
078          client.out.flush();
079        }
080        catch (Exception e) {
081          //
082        }
083    
084        // For now we suppose any impl return true;
085        return true;
086      }
087    
088      public boolean releaseAlternateBuffer() {
089        try {
090          client.out.writeObject(ServerMessage.USE_MAIN_BUFFER);
091          client.out.flush();
092        }
093        catch (Exception e) {
094          //
095        }
096    
097        // For now we suppose any impl return true;
098        return true;
099      }
100    
101      public String getProperty(String name) {
102        return null;
103      }
104    
105      public String readLine(String msg, boolean echo) {
106    //    try {
107    //      client.out.writeObject(ServerMessage.READLINE);
108    //      client.out.writeObject(msg);
109    //      client.out.writeObject(echo);
110    //      client.out.flush();
111    //      return (String)client.in.readObject();
112    //    }
113    //    catch (Exception e) {
114    //      return null;
115    //    }
116        return null;
117      }
118    
119      public void provide(Chunk element) throws IOException {
120        buffer.add(element);
121      }
122    
123      public synchronized void flush() {
124        if (buffer.size() > 0) {
125          try {
126            for (Chunk chunk : buffer) {
127              client.out.writeObject(ServerMessage.CHUNK);
128              client.out.writeObject(chunk);
129            }
130            client.out.writeObject(ServerMessage.FLUSH);
131            client.out.flush();
132          }
133          catch (IOException ignore) {
134            //
135          }
136          finally {
137            buffer.clear();
138          }
139        }
140      }
141    
142      public synchronized void end(ShellResponse response) {
143    
144        // Flush what we have in buffer first
145        flush();
146    
147        // Send end message
148        try {
149          client.current = null;
150          client.out.writeObject(ServerMessage.END);
151          client.out.writeObject(response);
152          client.out.flush();
153        }
154        catch (IOException ignore) {
155          //
156        }
157        finally {
158          if (response instanceof ShellResponse.Close) {
159            client.close();
160          }
161        }
162      }
163    }