/* * This file is part of the Vamsas Client version 0.1. * Copyright 2009 by Jim Procter, Iain Milne, Pierre Marguerite, * Andrew Waterhouse and Dominik Lindner. * * Earlier versions have also been incorporated into Jalview version 2.4 * since 2008, and TOPALi version 2 since 2007. * * The Vamsas Client is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The Vamsas Client is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the Vamsas Client. If not, see . */ package uk.ac.vamsas.client.picking; import java.io.*; import java.net.*; import java.util.logging.*; import org.apache.commons.logging.Log; class PickEndPoint extends Thread { private Log logger = org.apache.commons.logging.LogFactory .getLog(uk.ac.vamsas.client.picking.PickEndPoint.class); private Socket socket; private int rPort; private BufferedWriter os; private BufferedReader in; /** * reference to server or null if no comms session active */ private SocketManager manager; PickEndPoint(SocketManager manager, Socket s) { this.manager = manager; socket = s; } boolean openConnection() { try { // Create the socket if it doesn't already exist if (socket == null) socket = new Socket(InetAddress.getLocalHost(), PickServer.PORT); rPort = socket.getPort(); socket.setKeepAlive(true); // Open the streams for reading/writing os = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); in = new BufferedReader(new InputStreamReader(socket.getInputStream())); // Start the thread to listen for incoming messages logger.debug("CLIENT: connection successful to port " + socket.getPort() + " via port " + socket.getLocalPort()); start(); return true; } catch (Exception e) { logger.info("CLIENT: connection failed: " + e); return false; } } void send(Message message) { try { String str = message.getRawMessage(); // System.err.println("CLIENT: send " + str + " to " + rPort); os.write(str); // We use a newline to terminate the message os.newLine(); os.flush(); } catch (Exception e) { // logger.info("CLIENT: failed to send"); // TODO: terminate the connection on a failed send or retry? (Has this // been done? JBP) terminate(); } } // void receive() (threaded) public void run() { try { while (manager != null) { String str = in.readLine(); // logger.info("CLIENT: recv " + str + " from " + rPort); // TODO: Spawn this off into the GUI Event-Dispatch thread... // Convert the string back into something API friendly Message message = strToMessage(str); // Ignore corrupted or unknown message types if (message != null) manager.processMessage(this, message); } } catch (Exception e) { // Means the other end of the connection has (probably died) so we need // terminate this endpoint (if this is server side) // logger.info("CLIENT: read failed: " + e); terminate(); // this may not be necessary - probably caused infinite loop // on terminate() without null checks } } void terminate() { SocketManager mgr = manager; manager = null; // stops receive thread if (socket != null) { try { socket.close(); } catch (IOException e) { } socket = null; } // logger.info("CLIENT: closing connection to port " + socket.getPort()); // terminate() can be called by the socket manager to shutdown the // connection, // or the receive thread after an exception has been received // (which includes the above case when the socket is closed. // so we only want to removeEndPoint once - for the initial call to // terminate() if (mgr != null) mgr.removeEndPoint(this); } private Message strToMessage(String str) { try { // System.err.println("Received Message\n*\n"+str+"*"); if (str == null || str.length() == 1) return null; if (str.startsWith("CUSTOM")) return new CustomMessage(str.substring(6)); if (str.startsWith("MOUSEOVER")) return new MouseOverMessage(str); if (str.startsWith("SELECTION")) return new SelectionMessage(str); } catch (Exception e) { // logger.info("Unable to reconstruct message: " + e); } return null; } }