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 }