001 /*
002 $Id: ClientCommunication.java,v 1.11 2003/05/08 18:40:56 ndulgheru Exp $
003 */
004
005 package sharpster.daemon.clientcommunication;
006
007 import java.lang.Thread;
008 import java.net.*;
009 import java.io.*;
010 import sharpster.daemon.commandmanagement.InternalCommandManager;
011 import sharpster.common.ClientDaemonMessage;
012 import sharpster.common.ResponseCollection;
013 import sharpster.common.InternalMessageType;
014 import sharpster.common.Mutex;
015
016 /**
017 * Class responsible for handling the communication with the client.
018 *
019 */
020
021 public class ClientCommunication extends Thread {
022
023 private InternalCommandManager commandManager;
024 private ServerSocket serverSocket;
025 private boolean shutdownRequested;
026
027 private Mutex globalMutex;
028
029 /**
030 * Constructs a client communication object
031 */
032 public ClientCommunication(Mutex globalMutex) {
033 this.globalMutex = globalMutex;
034 shutdownRequested = false;
035 // which port to listen to.
036 int port = 7000;
037 // how long should we wait before timeout
038 int listenTimeout = 1000;
039 try {
040 serverSocket = new ServerSocket(port);
041 serverSocket.setSoTimeout(listenTimeout);
042 }
043 catch (IOException e) {
044 System.out.println(
045 "CC::constructor error: constructor error binding to port");
046 }
047 }
048
049 /**
050 *
051 */
052 public void initialize(InternalCommandManager icm) {
053 commandManager = icm;
054 }
055
056 /**
057 * Runs the thread
058 *
059 * When this method returns, the thread dies.
060 */
061 public void run() {
062 boolean exit_thread = false;
063 System.out.println("CC::run client communication thread has started");
064 while (!exit_thread) {
065 try {
066 Socket socket = serverSocket.accept();
067 receiveAndDelegate(socket);
068 }
069 catch (IOException timeoutException) {
070 if (shutdownRequested) {
071 try {
072 serverSocket.close();
073 }
074 catch (IOException closeException) {
075 System.out.println("CC::run error: couldn't close() serversocket");
076 }
077 exit_thread = true;
078 }
079 }
080 catch (Exception e) {
081 System.out.println("CC::run error: I was not initalized");
082 return;
083 }
084 }
085 System.out.println("CC::run I was told to shutdown");
086 }
087
088 /**
089 * Notifies the thread to stop
090 *
091 * Sets shtudownRequested and starts to wait for the thread with join()
092 */
093 public void shutdown() {
094 shutdownRequested = true;
095 System.out.println("CC::shutdown was called");
096 try {
097 this.join(); // wait for thread to die.
098 }
099 catch (java.lang.InterruptedException e) {
100 System.out.println("CC::thread has shutdown");
101 }
102 }
103
104 /**
105 * Waits for a commands sent by the local client, and forwards
106 * invocations the correct methods.
107 */
108 private void receiveAndDelegate(Socket socket) {
109 ClientDaemonMessage message = null;
110 ObjectInputStream ois = null;
111
112 /* try to receive the command from client */
113 try {
114 ois = new ObjectInputStream(socket.getInputStream());
115 message = (ClientDaemonMessage) ois.readObject();
116 }
117 catch (Exception e1) {
118 System.out.println("CC::receiveAndDelegate error:" +
119 " while receiving object");
120 try {
121 socket.close();
122 }
123 catch (Exception e2) {
124 /* do nothing */
125 }
126 return;
127 }
128
129 globalMutex.acquire();
130
131 switch (message.commandId) {
132 case InternalMessageType.SHARE_FILES:
133 if (null != message.files &&
134 null != message.workingDirectory) {
135 message.response =
136 commandManager.shareFiles(message.files,
137 message.workingDirectory);
138 }
139 break;
140 case InternalMessageType.UNSHARE_FILES:
141 if (null != message.files &&
142 null != message.workingDirectory) {
143 message.response =
144 commandManager.unshareFiles(message.files,
145 message.workingDirectory);
146 }
147 break;
148 case InternalMessageType.LOCAL_DO_CVS:
149 if (null != message.CVScommand &&
150 null != message.workingDirectory) {
151 message.response =
152 commandManager.localDoCVS(message.CVScommand,
153 message.workingDirectory);
154 }
155 break;
156 case InternalMessageType.REMOTE_CHECKOUT:
157 if (null != message.files &&
158 null != message.workingDirectory &&
159 null != message.fromUser) {
160 message.response =
161 commandManager.remoteCheckoutFiles(message.files,
162 message.fromUser,
163 message.workingDirectory,
164 message.role);
165 }
166 break;
167 case InternalMessageType.REMOTE_UPDATE:
168 if (null != message.files &&
169 null != message.workingDirectory &&
170 null != message.fromUser) {
171 message.response =
172 commandManager.remoteUpdateFiles(message.files,
173 message.fromUser,
174 message.workingDirectory);
175 }
176 break;
177 case InternalMessageType.REMOTE_COMMIT:
178 if (null != message.files &&
179 null != message.workingDirectory &&
180 null != message.fromUser) {
181 message.response =
182 commandManager.remoteCommitFiles(message.files,
183 message.fromUser,
184 message.workingDirectory,
185 message.role);
186 }
187 break;
188 case InternalMessageType.GROUP_COMMAND:
189 if (null != message.command) {
190 message.response =
191 commandManager.groupCommand(message.command);
192 }
193 break;
194
195 case InternalMessageType.REMOTE_ADD:
196 if (null != message.files &&
197 null != message.workingDirectory &&
198 null != message.fromUser) {
199 message.response =
200 commandManager.remoteAddFiles(message.files,
201 message.fromUser,
202 message.workingDirectory);
203 }
204 break;
205 case InternalMessageType.REMOTE_REMOVE:
206 if (null != message.files &&
207 null != message.workingDirectory &&
208 null != message.fromUser) {
209 message.response =
210 commandManager.remoteRemoveFiles(message.files,
211 message.fromUser,
212 message.workingDirectory);
213 }
214 break;
215 case InternalMessageType.VIEW_SHARING:
216 message.response =
217 commandManager.viewFileSharing();
218 break;
219 case InternalMessageType.VIEW_USERS:
220 message.response =
221 commandManager.viewUsers();
222 break;
223 case InternalMessageType.VIEW_ACCESS:
224 message.response =
225 commandManager.viewFileAccess();
226 break;
227 case InternalMessageType.SYNCHRONIZE_CVS:
228 if (null != message.workingDirectory) {
229 message.response =
230 commandManager.synchronizeCVS(message.workingDirectory);
231 }
232 break;
233 default:
234 System.out.println("CC:: receiveAndDelegate got illegal request\n");
235 break;
236 }
237
238 globalMutex.release();
239
240 /* try to send responce to client */
241 ObjectOutputStream oos = null;
242 try {
243 oos = new ObjectOutputStream(socket.getOutputStream());
244 oos.writeObject(message);
245 oos.flush();
246 }
247 catch (Exception e1) {
248 System.out.println("CC::receiveAndDelegate error: " +
249 "writing client response");
250 try {
251 oos.close();
252 ois.close();
253 socket.close();
254 }
255 catch (Exception e2) {
256 /* do nothing */
257 }
258 return;
259 }
260
261 try {
262 ois.close();
263 oos.close();
264 socket.close();
265 }
266 catch (IOException e) {
267 System.out.println(
268 "CC::receiveAndDelegate error: couldn't close() socket");
269 }
270 }
271 }