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    }