TcpConnection.java

    1/*******************************************************************************
    2 * Copyright (c) 2009, 2010 Mountainminds GmbH & Co. KG and Contributors
    3 * All rights reserved. This program and the accompanying materials
    4 * are made available under the terms of the Eclipse Public License v1.0
    5 * which accompanies this distribution, and is available at
    6 * http://www.eclipse.org/legal/epl-v10.html
    7 *
    8 * Contributors:
    9 *    Marc R. Hoffmann - initial API and implementation
   10 *    
   11 *******************************************************************************/
   12package org.jacoco.agent.rt.controller;
   13
   14import java.io.IOException;
   15import java.net.Socket;
   16import java.net.SocketException;
   17
   18import org.jacoco.core.runtime.IRemoteCommandVisitor;
   19import org.jacoco.core.runtime.IRuntime;
   20import org.jacoco.core.runtime.RemoteControlReader;
   21import org.jacoco.core.runtime.RemoteControlWriter;
   22
   23/**
   24 * Handler for a single socket based remote connection.
   25 * 
   26 * @author Marc R. Hoffmann
   27 * @version 0.4.1.20101007204400
   28 */
   29class TcpConnection implements IRemoteCommandVisitor {
   30
   31    private final IRuntime runtime;
   32
   33    private final Socket socket;
   34
   35    private RemoteControlWriter writer;
   36
   37    private RemoteControlReader reader;
   38
   39    private boolean initialized;
   40
   41    public TcpConnection(Socket socket, IRuntime runtime) {
   42        this.socket = socket;
   43        this.runtime = runtime;
   44        this.initialized = false;
   45    }
   46
   47    public void init() throws IOException {
   48        this.writer = new RemoteControlWriter(socket.getOutputStream());
   49        this.reader = new RemoteControlReader(socket.getInputStream());
   50        this.reader.setRemoteCommandVisitor(this);
   51        this.initialized = true;
   52    }
   53
   54    /**
   55     * Processes all requests for this session until the socket is closed.
   56     */
   57    public void run() throws IOException {
   58        try {
   59            while (reader.read()) {
   60            }
   61        } catch (SocketException e) {
   62            // If the local socket is closed while polling for commands the
   63            // SocketException is expected.
   64            if (!socket.isClosed()) {
   65                throw e;
   66            }
   67        } finally {
   68            close();
   69        }
   70    }
   71
   72    /**
   73     * Dumps the current execution data if the connection is already initialized
   74     * and the underlying socket is still open.
   75     * 
   76     * @throws IOException
   77     */
   78    public void writeExecutionData() throws IOException {
   79        if (initialized && !socket.isClosed()) {
   80            visitDumpCommand(true, false);
   81        }
   82    }
   83
   84    /**
   85     * Closes the underlying socket if not closed yet.
   86     * 
   87     * @throws IOException
   88     */
   89    public void close() throws IOException {
   90        if (!socket.isClosed()) {
   91            socket.close();
   92        }
   93    }
   94
   95    // === IRemoteCommandVisitor ===
   96
   97    public void visitDumpCommand(boolean dump, boolean reset) {
   98        if (dump) {
   99            runtime.collect(writer, writer, reset);
  100        } else {
  101            if (reset) {
  102                runtime.reset();
  103            }
  104        }
  105        writer.sendCmdOk();
  106    }
  107
  108}