/******************************************************************************* * Copyright (c) 2011, Christian Gruber and MEDEVIT OG * All rights reserved. *******************************************************************************/ package at.gruber.elexis.mythic22.netlistener; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.BindException; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketTimeoutException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.ui.statushandlers.StatusManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import at.gruber.elexis.mythic22.Activator; import at.gruber.elexis.mythic22.inputhandler.InputHandler; import at.gruber.elexis.mythic22.model.Mythic22Result; import at.gruber.elexis.mythic22.persistency.PersistencyHandler; public class NetListener implements Runnable { private static Logger logger = LoggerFactory.getLogger(NetListener.class); private static final String START = "MYTHIC"; private static final String END = "END_RESULT"; private int m_serverPort; private static boolean m_running = false; private Thread m_thread; private Socket m_socket; private ServerSocket m_serverSocket; public NetListener(int serverPort){ super(); m_serverPort = serverPort; } /** * Invokes a new Thread and starts it. This thread will process all incoming results from * mythic22 */ public void startContinousRead(){ // TODO IF we are still in Thread state RUNNABLE we face an IllegalThreadException here if (m_thread == null || (m_thread.getState() == Thread.State.TERMINATED)) { m_thread = new Thread(this); } // System.out.println(m_thread.getState()); m_serverSocket = null; m_socket = null; m_running = true; m_thread.start(); } /** * tries to read one Mythic22 output from start to end and returns the output on success if it * fails to read the whole output or an output at all null is returned * * @return null or the mythic22 output as a String */ private String readFromServer(){ boolean mythicHeaderFound = false; boolean mythicEndReached = false; StringBuilder strBuilder = new StringBuilder(); try { if (m_serverSocket == null || m_serverSocket.isClosed()) { m_serverSocket = new ServerSocket(m_serverPort); m_serverSocket.setSoTimeout(5000); } m_socket = m_serverSocket.accept(); BufferedReader in = new BufferedReader(new InputStreamReader(m_socket.getInputStream())); String temp; while (!mythicEndReached && (temp = in.readLine()) != null) { if (temp.startsWith(START)) { mythicHeaderFound = true; } else if (temp.startsWith(END)) { mythicEndReached = true; } if (mythicHeaderFound) { strBuilder.append(temp); strBuilder.append('\n'); } } in.close(); m_socket.close(); if (mythicHeaderFound == true && mythicEndReached == true) { return strBuilder.toString(); } else { return null; } } catch (IOException e) { if(e instanceof BindException) { requestThreadToStop(); } if (e instanceof SocketTimeoutException) return null; String message = "Error on creation of server socket on port " + m_serverPort; Status status = new Status(IStatus.WARNING, Activator.PLUGIN_ID, message, e); StatusManager.getManager().handle(status, StatusManager.SHOW); logger.error(message, e); return null; } } /** * reads incoming mythic22 results, processes them using the InputHandler and saves them into * the database using the PersistencyHandler */ @Override public void run(){ logger.debug("Starting mythic 22 listener"); while (m_running) { String temp = readFromServer(); if (temp != null) { logger.debug("Got mythic 22 input of length " + temp.length()); Mythic22Result result = InputHandler.getInstance().processInput(temp); if (!PersistencyHandler.getInstance().persistMythicResult(result)) { String message = "Error persisting data!"; Status status = new Status(IStatus.WARNING, Activator.PLUGIN_ID, message); StatusManager.getManager().handle(status, StatusManager.SHOW); } } } logger.debug("Stopping mythic 22 listener"); try { if (m_serverSocket != null) { m_serverSocket.close(); m_serverSocket = null; } } catch (IOException e) { String message = "Error closing server socket on " + m_serverSocket.getLocalPort(); logger.warn(message, e); } } /** * request the continuous read Thread to stop */ public void requestThreadToStop(){ m_running = false; } public int getServerPort(){ return m_serverPort; } public static boolean isRunning(){ return m_running; } }