DumpTask.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 *    Brock Janiczak - initial API and implementation
   10 *    
   11 *******************************************************************************/
   12package org.jacoco.ant;
   13
   14import java.io.File;
   15import java.io.FileOutputStream;
   16import java.io.IOException;
   17import java.io.OutputStream;
   18import java.net.InetAddress;
   19import java.net.Socket;
   20
   21import org.apache.tools.ant.BuildException;
   22import org.apache.tools.ant.Task;
   23import org.apache.tools.ant.util.FileUtils;
   24import org.jacoco.core.data.ExecutionDataWriter;
   25import org.jacoco.core.runtime.AgentOptions;
   26import org.jacoco.core.runtime.RemoteControlReader;
   27import org.jacoco.core.runtime.RemoteControlWriter;
   28
   29/**
   30 * Ant task for remotely controlling an application that is running with the
   31 * tcpserver output mode
   32 * 
   33 * @author Brock Janiczak
   34 * @version 0.4.1.20101007204400
   35 */
   36public class DumpTask extends Task {
   37    private boolean dump = true;
   38    private boolean reset;
   39    private File destfile;
   40    private String address = AgentOptions.DEFAULT_ADDRESS;
   41    private int port = AgentOptions.DEFAULT_PORT;
   42    private boolean append;
   43
   44    /**
   45     * Sets the location of the execution data file to write. This parameter is
   46     * required when dump is <code>true</code>. Default is
   47     * <code>jacoco.exec</code>
   48     * 
   49     * @param destfile
   50     *            Location to write execution data to
   51     */
   52    public void setDestFile(final File destfile) {
   53        this.destfile = destfile;
   54    }
   55
   56    /**
   57     * IP Address or hostname to connect to. Defaults to <code>localhost</code>
   58     * 
   59     * @param address
   60     *            IP Address or hostname to connect to
   61     */
   62    public void setAddress(final String address) {
   63        this.address = address;
   64    }
   65
   66    /**
   67     * Port number to connect to. Default is <code>6300</code>
   68     * 
   69     * @param port
   70     *            Port to connect to
   71     */
   72    public void setPort(final int port) {
   73        if (port <= 0) {
   74            throw new BuildException("Invalid port value");
   75        }
   76
   77        this.port = port;
   78    }
   79
   80    /**
   81     * <code>true</code> if the destination file it to be appended to.
   82     * <code>false</code> if the file is to be overwritten
   83     * 
   84     * @param append
   85     *            <code>true</code> if the destination file should be appended
   86     *            to
   87     */
   88    public void setAppend(final boolean append) {
   89        this.append = append;
   90    }
   91
   92    /**
   93     * Sets whether execution data should be downloaded from the remote host.
   94     * Defaults to <code>false</code>
   95     * 
   96     * @param dump
   97     *            <code>true</code> to download execution data
   98     */
   99    public void setDump(final boolean dump) {
  100        this.dump = dump;
  101    }
  102
  103    /**
  104     * Sets whether a reset command should be sent after the execution data has
  105     * been copied. Defaults to <code>false</code>
  106     * 
  107     * @param reset
  108     *            <code>true</code> to reset execution data
  109     */
  110    public void setReset(final boolean reset) {
  111        this.reset = reset;
  112    }
  113
  114    @Override
  115    public void execute() throws BuildException {
  116
  117        OutputStream output = null;
  118
  119        try {
  120
  121            if (dump) {
  122                if (destfile == null) {
  123                    throw new BuildException(
  124                            "Destination file is required when dumping execution data");
  125                }
  126                FileUtils.getFileUtils().createNewFile(destfile, true);
  127                output = new FileOutputStream(destfile, append);
  128            } else {
  129                output = new Nul();
  130            }
  131
  132            final Socket socket = new Socket(InetAddress.getByName(address),
  133                    port);
  134            final RemoteControlWriter remoteWriter = new RemoteControlWriter(
  135                    socket.getOutputStream());
  136            final RemoteControlReader remoteReader = new RemoteControlReader(
  137                    socket.getInputStream());
  138            final ExecutionDataWriter outputWriter = new ExecutionDataWriter(
  139                    output);
  140            remoteReader.setSessionInfoVisitor(outputWriter);
  141            remoteReader.setExecutionDataVisitor(outputWriter);
  142
  143            remoteWriter.visitDumpCommand(dump, reset);
  144            // Read session and/or execution data
  145            remoteReader.read();
  146
  147            socket.close();
  148        } catch (final IOException e) {
  149            throw new BuildException("Unable to dump coverage data", e);
  150        } finally {
  151            FileUtils.close(output);
  152        }
  153    }
  154
  155    private static class Nul extends OutputStream {
  156        @Override
  157        public void write(final int b) throws IOException {
  158        }
  159    }
  160
  161}