package org.intrace.client.gui.helper; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.net.Socket; import java.util.Map; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import org.intrace.shared.AgentConfigConstants; public class ControlConnectionThread implements Runnable { public static interface IControlConnectionListener { public void setProgress(Map<String,String> progress); public void setStatus(Map<String,String> progress); public void setConfig(Map<String,String> progress); public void disconnect(); } private final Socket socket; private final IControlConnectionListener listener; private final BlockingQueue<String> incomingMessages = new LinkedBlockingQueue<String>(); private final BlockingQueue<String> outgoingMessages = new LinkedBlockingQueue<String>(); private final ControlConnectionSenderThread senderThread = new ControlConnectionSenderThread(); private Thread sendThread; public ControlConnectionThread(Socket socket, IControlConnectionListener listener) { this.listener = listener; this.socket = socket; } public void start() { Thread receiveThread = new Thread(this); receiveThread.setDaemon(true); receiveThread.setName("Control Receive Thread"); receiveThread.start(); sendThread = new Thread(senderThread); sendThread.setDaemon(true); sendThread.setName("Control Sender Thread"); sendThread.start(); } public String getMessage() { try { return incomingMessages.take(); } catch (InterruptedException e) { return null; } } @SuppressWarnings("unchecked") @Override public void run() { try { while (true) { ObjectInputStream objIn = new ObjectInputStream(socket.getInputStream()); Object receivedMessage = objIn.readObject(); if (receivedMessage instanceof Map<?, ?>) { Map<String, String> map = (Map<String, String>) receivedMessage; if (map.containsKey(AgentConfigConstants.NUM_PROGRESS_ID)) { listener.setProgress(map); } else if (map.containsKey(AgentConfigConstants.STID)) { listener.setStatus(map); } else { listener.setConfig(map); } } else { String strMessage = (String) receivedMessage; if (!"OK".equals(strMessage)) { incomingMessages.put(strMessage); } } } } catch (Exception ex) { if (!ex.getMessage().contains("ocket closed") && !ex.getMessage().contains("onnection reset")) { ex.printStackTrace(); } listener.disconnect(); } } public void disconnect() { if (sendThread != null) { sendThread.interrupt(); } try { socket.close(); } catch (IOException e) { // Throw away } } public void sendMessage(String xiString) { try { outgoingMessages.put(xiString); } catch (InterruptedException e1) { // Throw away } } private class ControlConnectionSenderThread implements Runnable { @Override public void run() { try { while (true) { String message = outgoingMessages.take(); OutputStream out = socket.getOutputStream(); ObjectOutputStream objOut = new ObjectOutputStream(out); objOut.writeObject(message); objOut.flush(); } } catch (Exception e) { listener.disconnect(); } } } }