new Selection message. This still needs work!
[vamsas.git] / src / uk / ac / vamsas / client / picking / PickEndPoint.java
1 package uk.ac.vamsas.client.picking;\r
2 \r
3 import java.io.*;\r
4 import java.net.*;\r
5 import java.util.logging.*;\r
6 \r
7 import org.apache.commons.logging.Log;\r
8 \r
9 class PickEndPoint extends Thread\r
10 {\r
11         private Log logger = org.apache.commons.logging.LogFactory.getLog(uk.ac.vamsas.client.picking.PickEndPoint.class);\r
12         \r
13         private Socket socket;\r
14         private int rPort;\r
15         private BufferedWriter os;\r
16         private BufferedReader in;\r
17         /**\r
18    * reference to server or null if no comms session active\r
19    */\r
20         private SocketManager manager;  \r
21         \r
22         PickEndPoint(SocketManager manager, Socket s)\r
23         {\r
24                 this.manager = manager;\r
25                 socket = s;\r
26         }\r
27         \r
28         boolean openConnection()\r
29         {\r
30                 try\r
31                 {\r
32                         // Create the socket if it doesn't already exist\r
33                         if (socket == null)\r
34                                 socket = new Socket(InetAddress.getLocalHost(), PickServer.PORT);\r
35                         \r
36                         rPort = socket.getPort();\r
37                         socket.setKeepAlive(true);\r
38                                                 \r
39                         // Open the streams for reading/writing\r
40                         os = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));\r
41                         in = new BufferedReader(new InputStreamReader(socket.getInputStream()));\r
42                 \r
43                         // Start the thread to listen for incoming messages\r
44                         logger.debug("CLIENT: connection successful to port "\r
45                                 + socket.getPort() + " via port " + socket.getLocalPort());\r
46                         start();\r
47                         \r
48                         return true;\r
49                 }\r
50                 catch (Exception e)\r
51                 {\r
52                         logger.info("CLIENT: connection failed: " + e);\r
53                         return false;\r
54                 }\r
55         }\r
56         \r
57         void send(Message message)\r
58         {\r
59                 try\r
60                 {\r
61                         String str = message.getRawMessage();\r
62                         \r
63                         // System.err.println("CLIENT: send " + str + " to " + rPort);\r
64                         os.write(str);\r
65                         \r
66                         // We use a newline to terminate the message\r
67                         os.newLine();\r
68                         os.flush();\r
69                 }\r
70                 catch (Exception e)\r
71                 {\r
72                         //logger.info("CLIENT: failed to send");\r
73                         \r
74                         // TODO: terminate the connection on a failed send or retry? (Has this been done? JBP)\r
75                         terminate();\r
76                 }\r
77         }\r
78         \r
79         // void receive() (threaded)\r
80         public void run()\r
81         {\r
82                 try\r
83                 {\r
84                         while (manager!=null)\r
85                         {\r
86                                 String str = in.readLine();                             \r
87                                 //logger.info("CLIENT: recv " + str + " from " + rPort);\r
88                                 \r
89                                 // TODO: Spawn this off into the GUI Event-Dispatch thread...\r
90                                 \r
91                                 // Convert the string back into something API friendly\r
92                                 Message message = strToMessage(str);\r
93                                 \r
94                                 // Ignore corrupted or unknown message types\r
95                                 if (message != null)                            \r
96                                         manager.processMessage(this, message);\r
97                         }\r
98                 }\r
99                 catch (Exception e)\r
100                 {\r
101                         // Means the other end of the connection has (probably died) so we need\r
102                         // terminate this endpoint (if this is server side)\r
103                         //logger.info("CLIENT: read failed: " + e);\r
104                                                 \r
105                         terminate(); // this may not be necessary - probably caused infinite loop on terminate() without null checks\r
106                 }\r
107         }\r
108         \r
109         void terminate()\r
110         {\r
111     SocketManager mgr=manager;\r
112     manager=null; // stops receive thread\r
113                 if (socket!=null) {\r
114       try { socket.close(); }\r
115       catch (IOException e) {}\r
116       socket=null;\r
117     }\r
118     //logger.info("CLIENT: closing connection to port " + socket.getPort());\r
119                 // terminate() can be called by the socket manager to shutdown the connection,\r
120     // or the receive thread after an exception has been received\r
121     // (which includes the above case when the socket is closed.\r
122     //  so we only want to removeEndPoint once - for the initial call to terminate()\r
123     if (mgr!=null)\r
124       mgr.removeEndPoint(this);\r
125         }\r
126         \r
127         private Message strToMessage(String str)\r
128         {\r
129                 try\r
130                 {\r
131                   // System.err.println("Received Message\n*\n"+str+"*");\r
132       if (str==null || str.length()==1)\r
133         return null;\r
134                         if (str.startsWith("CUSTOM"))\r
135                                 return new CustomMessage(str.substring(6));\r
136                         if (str.startsWith("MOUSEOVER"))\r
137                                 return new MouseOverMessage(str);\r
138                         if (str.startsWith("SELECTION"))\r
139         return new SelectionMessage(str);\r
140       \r
141                 }\r
142                 catch (Exception e)\r
143                 {\r
144                         //logger.info("Unable to reconstruct message: " + e);\r
145                 }\r
146                 \r
147                 return null;\r
148         }\r
149 }