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 }