View Javadoc

1   package org.sourceforge.jemm.comm.server;
2   
3   import java.util.Map;
4   import java.util.concurrent.CountDownLatch;
5   import java.util.concurrent.ExecutorService;
6   
7   import org.sourceforge.jemm.comm.connection.Connection;
8   import org.sourceforge.jemm.comm.shared.RPCHandler;
9   import org.sourceforge.jemm.comm.shared.RPCHandlerListener;
10  
11  /**
12   * ServerThread is used by RPCServer for handling individual client connections.
13   * 
14   * <i><P>Released under the <a href="http://www.apache.org/licenses/LICENSE-2.0.html">Apache License V2.0 license</a> 
15   * by the <a href="http://jemm.sourceforge.net">JEMM Project</a></i>
16   *
17   * @author Rory Graves
18   */
19  public class ServerThread implements RPCHandlerListener {
20  	
21      protected CountDownLatch shutdownLatch = new CountDownLatch(1);
22      
23      protected volatile boolean connected;
24  
25      protected RPCClientId clientId;
26  
27      protected RPCServer server;
28  
29      protected RPCHandler rpcHandler;
30  
31      protected Connection connection;
32  
33      /**
34       * Creates a server thread to handle a specific client connection.
35       * 
36       * @param server The server instance this client belongs to
37       * @param connection The client socket
38       * @param clientId The server assigned client id;
39       * @param offeredIfs The interfaces offered to the client by the server
40       * @param threadPool The threadpool to use for servicing requests
41       */
42      public ServerThread(RPCServer server, Connection connection, 
43      		RPCClientId clientId,Map<Class<?>,Object> offeredIfs,ExecutorService threadPool) {
44          this.server = server;
45          this.connection = connection;
46          this.clientId = clientId;
47          this.connected = false;
48          
49          rpcHandler = new RPCHandler(false,connection,offeredIfs,threadPool,clientId);
50          rpcHandler.setHandlerListener(this);
51      }
52  
53      /**
54       * Start the server thread, initialising the connection and listening to 
55       * client requests.
56       */
57      public void start() {
58          connected = true;
59          rpcHandler.initialise();
60          server.notifyNewClient(clientId,connection.getConnectionName());        
61          rpcHandler.start();
62      }
63      
64      /**
65       * Notification that the connection has been closed.
66       */
67      public void connectionTerminated() {
68          if(connected)   
69              shutdown();
70      }
71  
72      /**
73       * Shutdown the thread by closing its socket connection.
74       */
75      public void shutdown() {
76          if(connected) {
77              connected = false;
78              rpcHandler.close();
79              server.clientDisconnected(clientId);
80              shutdownLatch.countDown();
81          }
82      }
83  
84      /**
85       * Utility method to allow a thread to wait for this thread to have completely
86       * terminated.  This method will return immediately if the thread is already stopped, 
87       * otherwise it will wait until all shutdown actions have completed before returning.
88       */
89      public void waitForShutdown() {
90          try {
91              shutdownLatch.await();
92          } catch (InterruptedException e) {
93              // do nothing 
94          }
95      }
96      /**
97       * Gets the proxy for the given client interface.
98       * @param ifClass The requesting interface implementation. 
99       * @return A proxy that implements the interface 'ifClass'
100      */
101     public Object getClientIF(Class<?> ifClass) {
102         return rpcHandler.getRemoteIF(ifClass);
103     }
104 }