1 /*******************************************************************************
2  * Copyright (c) 2009, 2018 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 java.io.File;
15 import java.io.IOException;
16 
17 import org.apache.tools.ant.BuildException;
18 import org.apache.tools.ant.Task;
19 import org.jacoco.agent.AgentJar;
20 import org.jacoco.core.runtime.AgentOptions;
21 import org.jacoco.core.runtime.AgentOptions.OutputMode;
22 
23 /**
24  * Base class for all coverage tasks that require agent options
25  */
26 public class AbstractCoverageTask extends Task {
27 
28 	private final AgentOptions agentOptions;
29 
30 	private File destfile;
31 
32 	private boolean enabled;
33 
34 	/**
35 	 * Create default agent options
36 	 */
AbstractCoverageTask()37 	protected AbstractCoverageTask() {
38 		super();
39 		agentOptions = new AgentOptions();
40 		destfile = new File(AgentOptions.DEFAULT_DESTFILE);
41 		enabled = true;
42 	}
43 
44 	/**
45 	 * @return Whether or not the current task is enabled
46 	 */
isEnabled()47 	public boolean isEnabled() {
48 		return enabled;
49 	}
50 
51 	/**
52 	 * Sets whether or not the current task is enabled
53 	 *
54 	 * @param enabled
55 	 *            Enablement state of the task
56 	 */
setEnabled(final boolean enabled)57 	public void setEnabled(final boolean enabled) {
58 		this.enabled = enabled;
59 	}
60 
61 	/**
62 	 * Sets the location to write coverage execution data to. Default is
63 	 * <code>jacoco.exec</code>.
64 	 *
65 	 * @param file
66 	 *            Location to write coverage execution data to
67 	 */
setDestfile(final File file)68 	public void setDestfile(final File file) {
69 		destfile = file;
70 	}
71 
72 	/**
73 	 * Append execution coverage data if a coverage file is already present.
74 	 * Default is <code>true</code>
75 	 *
76 	 * @param append
77 	 *            <code>true</code> to append execution data to an existing file
78 	 */
setAppend(final boolean append)79 	public void setAppend(final boolean append) {
80 		agentOptions.setAppend(append);
81 	}
82 
83 	/**
84 	 * List of wildcard patterns classes to include for instrumentation. Default
85 	 * is <code>*</code>
86 	 *
87 	 * @param includes
88 	 *            Wildcard pattern of included classes
89 	 */
setIncludes(final String includes)90 	public void setIncludes(final String includes) {
91 		agentOptions.setIncludes(includes);
92 	}
93 
94 	/**
95 	 * List of wildcard patterns classes to exclude from instrumentation.
96 	 * Default is the empty string, no classes excluded
97 	 *
98 	 * @param excludes
99 	 *            Wildcard pattern of excluded classes
100 	 */
setExcludes(final String excludes)101 	public void setExcludes(final String excludes) {
102 		agentOptions.setExcludes(excludes);
103 	}
104 
105 	/**
106 	 * List of wildcard patterns for classloaders that JaCoCo will not
107 	 * instrument classes from. Default is
108 	 * <code>sun.reflect.DelegatingClassLoader</code>
109 	 *
110 	 * @param exclClassLoader
111 	 *            Wildcard pattern of class loaders to exclude
112 	 */
setExclClassLoader(final String exclClassLoader)113 	public void setExclClassLoader(final String exclClassLoader) {
114 		agentOptions.setExclClassloader(exclClassLoader);
115 	}
116 
117 	/**
118 	 * Sets whether classes from the bootstrap classloader should be
119 	 * instrumented.
120 	 *
121 	 * @param include
122 	 *            <code>true</code> if bootstrap classes should be instrumented
123 	 */
setInclBootstrapClasses(final boolean include)124 	public void setInclBootstrapClasses(final boolean include) {
125 		agentOptions.setInclBootstrapClasses(include);
126 	}
127 
128 	/**
129 	 * Sets whether classes without source location should be instrumented.
130 	 *
131 	 * @param include
132 	 *            <code>true</code> if classes without source location should be
133 	 *            instrumented
134 	 */
setInclNoLocationClasses(final boolean include)135 	public void setInclNoLocationClasses(final boolean include) {
136 		agentOptions.setInclNoLocationClasses(include);
137 	}
138 
139 	/**
140 	 * Sets the session identifier. Default is a auto-generated id
141 	 *
142 	 * @param id
143 	 *            session identifier
144 	 */
setSessionId(final String id)145 	public void setSessionId(final String id) {
146 		agentOptions.setSessionId(id);
147 	}
148 
149 	/**
150 	 * Dump coverage data on VM termination. Default is <code>true</code>
151 	 *
152 	 * @param dumpOnExit
153 	 *            <code>true</code> to write coverage data on VM termination
154 	 */
setDumpOnExit(final boolean dumpOnExit)155 	public void setDumpOnExit(final boolean dumpOnExit) {
156 		agentOptions.setDumpOnExit(dumpOnExit);
157 	}
158 
159 	/**
160 	 * Sets the output method. Default is <code>file</code>
161 	 *
162 	 * @param output
163 	 *            Output method
164 	 */
setOutput(final String output)165 	public void setOutput(final String output) {
166 		agentOptions.setOutput(output);
167 	}
168 
169 	/**
170 	 * Sets the IP address or hostname to bind to when output method is tcp
171 	 * server or connect to when the output method is tcp client. Default is
172 	 * <code>localhost</code>
173 	 *
174 	 * @param address
175 	 *            Address to bind or connect to
176 	 */
setAddress(final String address)177 	public void setAddress(final String address) {
178 		agentOptions.setAddress(address);
179 	}
180 
181 	/**
182 	 * Sets the Port to bind to when the output method is tcp server or connect
183 	 * to when the output method is tcp client. Default is <code>6300</code>
184 	 *
185 	 * @param port
186 	 *            port to bind to or connect to
187 	 */
setPort(final int port)188 	public void setPort(final int port) {
189 		agentOptions.setPort(port);
190 	}
191 
192 	/**
193 	 * Sets the directory where all class files seen by the agent should be
194 	 * dumped to.
195 	 *
196 	 * @param dir
197 	 *            dump output location
198 	 */
setClassdumpdir(final File dir)199 	public void setClassdumpdir(final File dir) {
200 		agentOptions.setClassDumpDir(dir.getAbsolutePath());
201 	}
202 
203 	/**
204 	 * Sets whether the agent should expose functionality via JMX.
205 	 *
206 	 * @param jmx
207 	 *            <code>true</code> if JMX should be enabled
208 	 */
setJmx(final boolean jmx)209 	public void setJmx(final boolean jmx) {
210 		agentOptions.setJmx(jmx);
211 	}
212 
213 	/**
214 	 * Creates JVM argument to launch with the specified JaCoCo agent jar and
215 	 * the current options
216 	 *
217 	 * @return JVM Argument to pass to new VM
218 	 */
getLaunchingArgument()219 	protected String getLaunchingArgument() {
220 		return prepareAgentOptions().getVMArgument(getAgentFile());
221 	}
222 
prepareAgentOptions()223 	private AgentOptions prepareAgentOptions() {
224 		if (OutputMode.file.equals(agentOptions.getOutput())) {
225 			agentOptions.setDestfile(destfile.getAbsolutePath());
226 		}
227 		return agentOptions;
228 	}
229 
getAgentFile()230 	private File getAgentFile() {
231 		try {
232 			File agentFile = null;
233 			final String agentFileLocation = getProject().getProperty(
234 					"_jacoco.agentFile");
235 			if (agentFileLocation != null) {
236 				agentFile = new File(agentFileLocation);
237 			} else {
238 				agentFile = AgentJar.extractToTempLocation();
239 				getProject().setProperty("_jacoco.agentFile",
240 						agentFile.toString());
241 			}
242 
243 			return agentFile;
244 		} catch (final IOException e) {
245 			throw new BuildException("Unable to extract agent jar", e,
246 					getLocation());
247 		}
248 	}
249 
250 }
251