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}