1/*******************************************************************************
2 * Copyright (c) 2000, 2004 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.html
7 *
8 * Contributors:
9 *     IBM Corporation - initial API and implementation
10 *     Julien Ruaux: jruaux@octo.com
11 *     Vincent Massol: vmassol@octo.com
12 *
13 * Adapted by:
14 *     Alexandru Popescu: the_mindstorm@evolva.ro
15 ******************************************************************************/
16package org.testng.remote.strprotocol;
17
18
19import org.testng.TestNGException;
20
21import java.io.IOException;
22import java.net.ServerSocket;
23import java.net.Socket;
24
25/**
26 * The client side of the RemoteTestRunner. Handles the
27 * marshaling of the different messages.
28 */
29public abstract class AbstractRemoteTestRunnerClient {
30  /**
31   * An array of listeners that are informed about test events.
32   */
33  protected IRemoteSuiteListener[] m_suiteListeners;
34  protected IRemoteTestListener[] m_testListeners;
35
36  /**
37   * The server socket
38   */
39  private ServerSocket       fServerSocket;
40  private Socket             fSocket;
41  private ServerConnection m_serverConnection;
42//  private PrintWriter        m_outputWriter;
43//  private BufferedReader     m_inputReader;
44
45  /**
46   * Start listening to a test run. Start a server connection that
47   * the RemoteTestRunner can connect to.
48   */
49  public synchronized void startListening(IRemoteSuiteListener[] suiteListeners,
50                                          IRemoteTestListener[] testListeners,
51                                          ServerConnection serverConnection) {
52    m_suiteListeners= suiteListeners;
53    m_testListeners= testListeners;
54    m_serverConnection = serverConnection;
55
56    serverConnection.start();
57  }
58
59  public IRemoteSuiteListener[] getSuiteListeners() {
60    return m_suiteListeners;
61  }
62
63  public IRemoteTestListener[] getTestListeners() {
64    return m_testListeners;
65  }
66
67  private synchronized void shutdown() {
68//    if(m_outputWriter != null) {
69//      m_outputWriter.close();
70//      m_outputWriter = null;
71//    }
72//    try {
73//      if(m_inputReader != null) {
74//        m_inputReader.close();
75//        m_inputReader = null;
76//      }
77//    }
78//    catch(IOException e) {
79//      e.printStackTrace();
80//    }
81    try {
82      if(fSocket != null) {
83        fSocket.close();
84        fSocket = null;
85      }
86    }
87    catch(IOException e) {
88      e.printStackTrace();
89    }
90    try {
91      if(fServerSocket != null) {
92        fServerSocket.close();
93        fServerSocket = null;
94      }
95    }
96    catch(IOException e) {
97      e.printStackTrace();
98    }
99  }
100
101  public boolean isRunning() {
102    return m_serverConnection.getMessageSender() != null;
103  }
104
105  /**
106   * Requests to stop the remote test run.
107   */
108  public synchronized void stopTest() {
109    if(isRunning()) {
110      m_serverConnection.getMessageSender().sendStop();
111      shutdown();
112    }
113  }
114
115//  private String readMessage(BufferedReader in) throws IOException {
116//    return in.readLine();
117//  }
118//
119//  private void receiveMessage(String message) {
120//    int messageType = MessageHelper.getMessageType(message);
121//
122//    try {
123//      if(messageType < MessageHelper.SUITE) {
124//        // Generic message
125//        GenericMessage gm = MessageHelper.unmarshallGenericMessage(message);
126//        notifyStart(gm);
127//      }
128//      else if(messageType < MessageHelper.TEST) {
129//        // Suite message
130//        SuiteMessage sm = MessageHelper.createSuiteMessage(message);
131//        notifySuiteEvents(sm);
132//      }
133//      else if(messageType < MessageHelper.TEST_RESULT) {
134//        // Test message
135//        TestMessage tm = MessageHelper.createTestMessage(message);
136//        notifyTestEvents(tm);
137//      }
138//      else {
139//        // TestResult message
140//        TestResultMessage trm = MessageHelper.unmarshallTestResultMessage(message);
141//        notifyResultEvents(trm);
142//      }
143//    }
144//    finally {
145//      if(isRunning() && (null != m_outputWriter)) {
146//        m_outputWriter.println(MessageHelper.ACK_MSG);
147//        m_outputWriter.flush();
148//      }
149//    }
150//  }
151
152  protected abstract void notifyStart(final GenericMessage genericMessage);
153
154  protected abstract void notifySuiteEvents(final SuiteMessage suiteMessage);
155
156  protected abstract void notifyTestEvents(final TestMessage testMessage);
157
158  protected abstract void notifyResultEvents(final TestResultMessage testResultMessage);
159
160
161  /**
162   * Reads the message stream from the RemoteTestRunner
163   */
164  public abstract class ServerConnection extends Thread {
165    private MessageHub m_messageHub;
166
167    public ServerConnection(IMessageSender messageMarshaller) {
168      super("TestNG - ServerConnection"); //$NON-NLS-1$
169      m_messageHub = new MessageHub(messageMarshaller);
170    }
171
172    IMessageSender getMessageSender() {
173      return m_messageHub != null ? m_messageHub.getMessageSender() : null;
174    }
175
176    @Override
177    public void run() {
178      try {
179        IMessage message = m_messageHub.receiveMessage();
180        while (message != null) {
181          if (message instanceof GenericMessage) {
182            notifyStart((GenericMessage) message);
183          }
184          else if (message instanceof SuiteMessage) {
185            notifySuiteEvents((SuiteMessage) message);
186          }
187          else if (message instanceof TestMessage) {
188            notifyTestEvents((TestMessage) message);
189          }
190          else if (message instanceof TestResultMessage) {
191            notifyResultEvents((TestResultMessage) message);
192          }
193          else {
194            throw new TestNGException("Unknown message type:" + message);
195          }
196//          if (isRunning()) {
197//            m_messageMarshaller.sendAck();
198//          }
199          message = m_messageHub.receiveMessage();
200        }
201      }
202      finally {
203        m_messageHub.shutDown();
204        m_messageHub = null;
205      }
206//      try {
207//        fServerSocket = new ServerSocket(fServerPort);
208//        fSocket = fServerSocket.accept();
209//        try {
210//          m_inputReader = new BufferedReader(new InputStreamReader(fSocket.getInputStream(),
211//                                                                     "UTF-8")); //$NON-NLS-1$
212//        }
213//        catch(UnsupportedEncodingException e) {
214//          m_inputReader = new BufferedReader(new InputStreamReader(fSocket.getInputStream()));
215//        }
216//        try {
217//          m_outputWriter = new PrintWriter(new OutputStreamWriter(fSocket.getOutputStream(), "UTF-8"),
218//                                    true);
219//        }
220//        catch(UnsupportedEncodingException e1) {
221//          m_outputWriter = new PrintWriter(new OutputStreamWriter(fSocket.getOutputStream()), true);
222//        }
223//        String message;
224//        while((m_inputReader != null) && ((message = readMessage(m_inputReader)) != null)) {
225//          receiveMessage(message);
226//        }
227//      }
228//      catch(SocketException e) {
229//        handleThrowable(e);
230//      }
231//      catch(IOException e) {
232//        handleThrowable(e);
233//      }
234//      finally {
235//        shutdown();
236//      }
237    }
238
239    protected abstract void handleThrowable(Throwable cause);
240  }
241
242}
243