/******************************************************************************* * Copyright (c) 2000, 2004 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * Julien Ruaux: jruaux@octo.com * Vincent Massol: vmassol@octo.com * * Adapted by: * Alexandru Popescu: the_mindstorm@evolva.ro ******************************************************************************/ package org.testng.remote.strprotocol; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketException; /** * The client side of the RemoteTestRunner. Handles the * marshaling of the different messages. */ public abstract class AbstractRemoteTestRunnerClient { /** * An array of listeners that are informed about test events. */ protected IRemoteSuiteListener[] m_suiteListeners; protected IRemoteTestListener[] m_testListeners; /** * The server socket */ private ServerSocket fServerSocket; private Socket fSocket; private PrintWriter m_outputWriter; private BufferedReader m_inputReader; /** * Start listening to a test run. Start a server connection that * the RemoteTestRunner can connect to. */ public synchronized void startListening(IRemoteSuiteListener[] suiteListeners, IRemoteTestListener[] testListeners, ServerConnection serverConnection) { m_suiteListeners= suiteListeners; m_testListeners= testListeners; serverConnection.start(); } public IRemoteSuiteListener[] getSuiteListeners() { return m_suiteListeners; } public IRemoteTestListener[] getTestListeners() { return m_testListeners; } private synchronized void shutdown() { if(m_outputWriter != null) { m_outputWriter.close(); m_outputWriter = null; } try { if(m_inputReader != null) { m_inputReader.close(); m_inputReader = null; } } catch(IOException e) { e.printStackTrace(); } try { if(fSocket != null) { fSocket.close(); fSocket = null; } } catch(IOException e) { e.printStackTrace(); } try { if(fServerSocket != null) { fServerSocket.close(); fServerSocket = null; } } catch(IOException e) { e.printStackTrace(); } } public boolean isRunning() { return fSocket != null; } /** * Requests to stop the remote test run. */ public synchronized void stopTest() { if(isRunning()) { if(null != m_outputWriter) { m_outputWriter.println(MessageHelper.STOP_MSG); m_outputWriter.flush(); } shutdown(); } } private String readMessage(BufferedReader in) throws IOException { return in.readLine(); } private void receiveMessage(String message) { int messageType = MessageHelper.getMessageType(message); try { if(messageType < MessageHelper.SUITE) { // Generic message GenericMessage gm = MessageHelper.unmarshallGenericMessage(message); notifyStart(gm); } else if(messageType < MessageHelper.TEST) { // Suite message SuiteMessage sm = MessageHelper.createSuiteMessage(message); notifySuiteEvents(sm); } else if(messageType < MessageHelper.TEST_RESULT) { // Test message TestMessage tm = MessageHelper.createTestMessage(message); notifyTestEvents(tm); } else { // TestResult message TestResultMessage trm = MessageHelper.unmarshallTestResultMessage(message); notifyResultEvents(trm); } } finally { if(isRunning() && (null != m_outputWriter)) { m_outputWriter.println(MessageHelper.ACK_MSG); m_outputWriter.flush(); } } } protected abstract void notifyStart(final GenericMessage genericMessage); protected abstract void notifySuiteEvents(final SuiteMessage suiteMessage); protected abstract void notifyTestEvents(final TestMessage testMessage); protected abstract void notifyResultEvents(final TestResultMessage testResultMessage); /** * Reads the message stream from the RemoteTestRunner */ public abstract class ServerConnection extends Thread { int fServerPort; public ServerConnection(int port) { super("ServerConnection"); //$NON-NLS-1$ fServerPort = port; } @Override public void run() { try { fServerSocket = new ServerSocket(fServerPort); fSocket = fServerSocket.accept(); try { m_inputReader = new BufferedReader(new InputStreamReader(fSocket.getInputStream(), "UTF-8")); //$NON-NLS-1$ } catch(UnsupportedEncodingException e) { m_inputReader = new BufferedReader(new InputStreamReader(fSocket.getInputStream())); } try { m_outputWriter = new PrintWriter(new OutputStreamWriter(fSocket.getOutputStream(), "UTF-8"), true); //$NON-NLS-1$ } catch(UnsupportedEncodingException e1) { m_outputWriter = new PrintWriter(new OutputStreamWriter(fSocket.getOutputStream()), true); } String message; while((m_inputReader != null) && ((message = readMessage(m_inputReader)) != null)) { receiveMessage(message); } } catch(SocketException e) { handleThrowable(e); } catch(IOException e) { handleThrowable(e); } finally { shutdown(); } } protected abstract void handleThrowable(Throwable cause); } }