1 /*******************************************************************************
2  * Copyright (c) 2009, 2015 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  *******************************************************************************/
12 package org.jacoco.ant;
13 
14 import static java.lang.String.format;
15 
16 import java.io.File;
17 import java.io.IOException;
18 import java.net.InetAddress;
19 
20 import org.apache.tools.ant.BuildException;
21 import org.apache.tools.ant.Task;
22 import org.jacoco.core.runtime.AgentOptions;
23 import org.jacoco.core.tools.ExecDumpClient;
24 import org.jacoco.core.tools.ExecFileLoader;
25 
26 /**
27  * Ant task for remotely controlling an application that is running with the
28  * tcpserver output mode
29  */
30 public class DumpTask extends Task {
31 
32 	private boolean dump = true;
33 	private boolean reset = false;
34 	private File destfile = null;
35 	private String address = AgentOptions.DEFAULT_ADDRESS;
36 	private int port = AgentOptions.DEFAULT_PORT;
37 	private int retryCount = 10;
38 	private boolean append = true;
39 
40 	/**
41 	 * Sets the location of the execution data file to write. This parameter is
42 	 * required when dump is <code>true</code>. Default is
43 	 * <code>jacoco.exec</code>
44 	 *
45 	 * @param destfile
46 	 *            Location to write execution data to
47 	 */
setDestfile(final File destfile)48 	public void setDestfile(final File destfile) {
49 		this.destfile = destfile;
50 	}
51 
52 	/**
53 	 * IP Address or hostname to connect to. Defaults to <code>localhost</code>
54 	 *
55 	 * @param address
56 	 *            IP Address or hostname to connect to
57 	 */
setAddress(final String address)58 	public void setAddress(final String address) {
59 		this.address = address;
60 	}
61 
62 	/**
63 	 * Port number to connect to. Default is <code>6300</code>
64 	 *
65 	 * @param port
66 	 *            Port to connect to
67 	 */
setPort(final int port)68 	public void setPort(final int port) {
69 		this.port = port;
70 	}
71 
72 	/**
73 	 * Number of retries which the goal will attempt to establish a connection.
74 	 * This can be used to wait until the target JVM is successfully launched.
75 	 *
76 	 * @param retryCount
77 	 *            number of retries
78 	 */
setRetryCount(final int retryCount)79 	public void setRetryCount(final int retryCount) {
80 		this.retryCount = retryCount;
81 	}
82 
83 	/**
84 	 * <code>true</code> if the destination file it to be appended to.
85 	 * <code>false</code> if the file is to be overwritten
86 	 *
87 	 * @param append
88 	 *            <code>true</code> if the destination file should be appended
89 	 *            to
90 	 */
setAppend(final boolean append)91 	public void setAppend(final boolean append) {
92 		this.append = append;
93 	}
94 
95 	/**
96 	 * Sets whether execution data should be downloaded from the remote host.
97 	 * Defaults to <code>true</code>
98 	 *
99 	 * @param dump
100 	 *            <code>true</code> to download execution data
101 	 */
setDump(final boolean dump)102 	public void setDump(final boolean dump) {
103 		this.dump = dump;
104 	}
105 
106 	/**
107 	 * Sets whether a reset command should be sent after the execution data has
108 	 * been dumped. Defaults to <code>false</code>
109 	 *
110 	 * @param reset
111 	 *            <code>true</code> to reset execution data
112 	 */
setReset(final boolean reset)113 	public void setReset(final boolean reset) {
114 		this.reset = reset;
115 	}
116 
117 	@Override
execute()118 	public void execute() throws BuildException {
119 
120 		if (port <= 0) {
121 			throw new BuildException("Invalid port value", getLocation());
122 		}
123 		if (dump && destfile == null) {
124 			throw new BuildException(
125 					"Destination file is required when dumping execution data",
126 					getLocation());
127 		}
128 
129 		final ExecDumpClient client = new ExecDumpClient() {
130 			@Override
131 			protected void onConnecting(final InetAddress address,
132 					final int port) {
133 				log(format("Connecting to %s:%s", address,
134 						Integer.valueOf(port)));
135 			}
136 
137 			@Override
138 			protected void onConnectionFailure(final IOException exception) {
139 				log(exception.getMessage());
140 			}
141 		};
142 		client.setDump(dump);
143 		client.setReset(reset);
144 		client.setRetryCount(retryCount);
145 
146 		try {
147 			final ExecFileLoader loader = client.dump(address, port);
148 			if (dump) {
149 				log(format("Dumping execution data to %s",
150 						destfile.getAbsolutePath()));
151 				loader.save(destfile, append);
152 			}
153 		} catch (final IOException e) {
154 			throw new BuildException("Unable to dump coverage data", e,
155 					getLocation());
156 		}
157 	}
158 
159 }
160