1e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov/*******************************************************************************
2b9d1b54e300318b470d9fedccc69d75187016444Evgeny Mandrikov * Copyright (c) 2009, 2018 Mountainminds GmbH & Co. KG and Contributors
3e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * All rights reserved. This program and the accompanying materials
4e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * are made available under the terms of the Eclipse Public License v1.0
5e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * which accompanies this distribution, and is available at
6e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * http://www.eclipse.org/legal/epl-v10.html
7e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov *
8e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * Contributors:
9e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov *    Marc R. Hoffmann - initial API and implementation
10e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov *
11e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov *******************************************************************************/
12e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikovpackage org.jacoco.core.runtime;
13e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
14e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikovimport static java.lang.String.format;
15e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
16e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikovimport java.io.File;
17e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikovimport java.util.Arrays;
18e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikovimport java.util.Collection;
19e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikovimport java.util.HashMap;
209fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmannimport java.util.Iterator;
219fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmannimport java.util.List;
22e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikovimport java.util.Map;
2325fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmannimport java.util.Properties;
24310ceffbcc17605116409cec60a67a2dc3de65b4jochenbergerimport java.util.regex.Pattern;
25e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
26e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov/**
27e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * Utility to create and parse options for the runtime agent. Options are
28e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * represented as a string in the following format:
29e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov *
30e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * <pre>
31e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov *   key1=value1,key2=value2,key3=value3
32e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * </pre>
33e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov */
34e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikovpublic final class AgentOptions {
35e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
36e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
37e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Specifies the output file for execution data. Default is
38e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * <code>jacoco.exec</code> in the working directory.
39e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
40e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public static final String DESTFILE = "destfile";
41e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
42e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
43d5946166388e92f67220bbece1f104e21ab7b0cbMarc R. Hoffmann	 * Default value for the "destfile" agent option.
44d5946166388e92f67220bbece1f104e21ab7b0cbMarc R. Hoffmann	 */
45d5946166388e92f67220bbece1f104e21ab7b0cbMarc R. Hoffmann	public static final String DEFAULT_DESTFILE = "jacoco.exec";
46d5946166388e92f67220bbece1f104e21ab7b0cbMarc R. Hoffmann
47d5946166388e92f67220bbece1f104e21ab7b0cbMarc R. Hoffmann	/**
48e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Specifies whether execution data should be appended to the output file.
49e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Default is <code>true</code>.
50e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
51e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public static final String APPEND = "append";
52e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
53e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
54e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Wildcard expression for class names that should be included for code
55e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * coverage. Default is <code>*</code> (all classes included).
56e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *
57e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @see WildcardMatcher
58e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
59e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public static final String INCLUDES = "includes";
60e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
61e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
62e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Wildcard expression for class names that should be excluded from code
63e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * coverage. Default is the empty string (no exclusions).
64e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *
65e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @see WildcardMatcher
66e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
67e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public static final String EXCLUDES = "excludes";
68e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
69e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
70e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Wildcard expression for class loaders names for classes that should be
71e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * excluded from code coverage. This means all classes loaded by a class
72e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * loader which full qualified name matches this expression will be ignored
73e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * for code coverage regardless of all other filtering settings. Default is
74e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * <code>sun.reflect.DelegatingClassLoader</code>.
75e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *
76e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @see WildcardMatcher
77e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
78e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public static final String EXCLCLASSLOADER = "exclclassloader";
79e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
80e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
81310b7d14546c8f5e49f5e99475fb6001331ac4caMarc R. Hoffmann	 * Specifies whether also classes from the bootstrap classloader should be
82310b7d14546c8f5e49f5e99475fb6001331ac4caMarc R. Hoffmann	 * instrumented. Use this feature with caution, it needs heavy
83310b7d14546c8f5e49f5e99475fb6001331ac4caMarc R. Hoffmann	 * includes/excludes tuning. Default is <code>false</code>.
84310b7d14546c8f5e49f5e99475fb6001331ac4caMarc R. Hoffmann	 */
851d8389bf86f8a49d31bb5182b3ec1592e2f7289aMarc R. Hoffmann	public static final String INCLBOOTSTRAPCLASSES = "inclbootstrapclasses";
86310b7d14546c8f5e49f5e99475fb6001331ac4caMarc R. Hoffmann
87310b7d14546c8f5e49f5e99475fb6001331ac4caMarc R. Hoffmann	/**
8826daee44414eeecb0a7a63d7f6784fcf4cfe32faMarc R. Hoffmann	 * Specifies whether also classes without a source location should be
8926daee44414eeecb0a7a63d7f6784fcf4cfe32faMarc R. Hoffmann	 * instrumented. Normally such classes are generated at runtime e.g. by
9026daee44414eeecb0a7a63d7f6784fcf4cfe32faMarc R. Hoffmann	 * mocking frameworks and are therefore excluded by default. Default is
9126daee44414eeecb0a7a63d7f6784fcf4cfe32faMarc R. Hoffmann	 * <code>false</code>.
9226daee44414eeecb0a7a63d7f6784fcf4cfe32faMarc R. Hoffmann	 */
9326daee44414eeecb0a7a63d7f6784fcf4cfe32faMarc R. Hoffmann	public static final String INCLNOLOCATIONCLASSES = "inclnolocationclasses";
9426daee44414eeecb0a7a63d7f6784fcf4cfe32faMarc R. Hoffmann
9526daee44414eeecb0a7a63d7f6784fcf4cfe32faMarc R. Hoffmann	/**
96e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Specifies a session identifier that is written with the execution data.
97e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Without this parameter a random identifier is created by the agent.
98e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
99e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public static final String SESSIONID = "sessionid";
100e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
101e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
102e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Specifies whether the agent will automatically dump coverage data on VM
103e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * exit. Default is <code>true</code>.
104e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
105e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public static final String DUMPONEXIT = "dumponexit";
106e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
107e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
10857f7cf06888f1e34f9ab2e3129c3d433826ecbe1Marc R. Hoffmann	 * Specifies the output mode. Default is {@link OutputMode#file}.
109e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *
110e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @see OutputMode#file
111e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @see OutputMode#tcpserver
112e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @see OutputMode#tcpclient
1138c614bab37eee9dbf920a7b20a2b18ab1b8c20d4Evgeny Mandrikov	 * @see OutputMode#none
114e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
115e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public static final String OUTPUT = "output";
116e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
117e83313313ce1020fe203856446ca9bb2ce06f433Marc R. Hoffmann	private static final Pattern OPTION_SPLIT = Pattern
118e83313313ce1020fe203856446ca9bb2ce06f433Marc R. Hoffmann			.compile(",(?=[a-zA-Z0-9_\\-]+=)");
119e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
120e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
121e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Possible values for {@link AgentOptions#OUTPUT}.
122e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
123e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public static enum OutputMode {
124e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
125e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		/**
126e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		 * Value for the {@link AgentOptions#OUTPUT} parameter: At VM
127e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		 * termination execution data is written to the file specified by
128e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		 * {@link AgentOptions#DESTFILE}.
129e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		 */
130e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		file,
131e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
132e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		/**
133e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		 * Value for the {@link AgentOptions#OUTPUT} parameter: The agent
134e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		 * listens for incoming connections on a TCP port specified by
135e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		 * {@link AgentOptions#ADDRESS} and {@link AgentOptions#PORT}.
136e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		 */
137e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		tcpserver,
138e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
139e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		/**
140e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		 * Value for the {@link AgentOptions#OUTPUT} parameter: At startup the
141e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		 * agent connects to a TCP port specified by the
142e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		 * {@link AgentOptions#ADDRESS} and {@link AgentOptions#PORT} attribute.
143e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		 */
1448c614bab37eee9dbf920a7b20a2b18ab1b8c20d4Evgeny Mandrikov		tcpclient,
1458c614bab37eee9dbf920a7b20a2b18ab1b8c20d4Evgeny Mandrikov
1468c614bab37eee9dbf920a7b20a2b18ab1b8c20d4Evgeny Mandrikov		/**
1478c614bab37eee9dbf920a7b20a2b18ab1b8c20d4Evgeny Mandrikov		 * Value for the {@link AgentOptions#OUTPUT} parameter: Do not produce
1488c614bab37eee9dbf920a7b20a2b18ab1b8c20d4Evgeny Mandrikov		 * any output.
1498c614bab37eee9dbf920a7b20a2b18ab1b8c20d4Evgeny Mandrikov		 */
1508c614bab37eee9dbf920a7b20a2b18ab1b8c20d4Evgeny Mandrikov		none
151e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
152e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
153e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
154e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
155e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * The IP address or DNS name the tcpserver binds to or the tcpclient
156e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * connects to. Default is defined by {@link #DEFAULT_ADDRESS}.
157e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
158e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public static final String ADDRESS = "address";
159e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
160e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
161e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Default value for the "address" agent option.
162e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
163e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public static final String DEFAULT_ADDRESS = null;
164e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
165e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
166e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * The port the tcpserver binds to or the tcpclient connects to. In
167e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * tcpserver mode the port must be available, which means that if multiple
168e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * JaCoCo agents should run on the same machine, different ports have to be
169e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * specified. Default is defined by {@link #DEFAULT_PORT}.
170e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
171e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public static final String PORT = "port";
172e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
173e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
174e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Default value for the "port" agent option.
175e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
176e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public static final int DEFAULT_PORT = 6300;
177e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
178e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
179e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Specifies where the agent dumps all class files it encounters. The
180e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * location is specified as a relative path to the working directory.
181e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Default is <code>null</code> (no dumps).
182e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
183e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public static final String CLASSDUMPDIR = "classdumpdir";
184e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
185e2930e70cc2d5409732639f0bda3af36b27e6db4Marc R. Hoffmann	/**
186e2930e70cc2d5409732639f0bda3af36b27e6db4Marc R. Hoffmann	 * Specifies whether the agent should expose functionality via JMX under the
187e2930e70cc2d5409732639f0bda3af36b27e6db4Marc R. Hoffmann	 * name "org.jacoco:type=Runtime". Default is <code>false</code>.
188e2930e70cc2d5409732639f0bda3af36b27e6db4Marc R. Hoffmann	 */
189e2930e70cc2d5409732639f0bda3af36b27e6db4Marc R. Hoffmann	public static final String JMX = "jmx";
190e2930e70cc2d5409732639f0bda3af36b27e6db4Marc R. Hoffmann
191e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	private static final Collection<String> VALID_OPTIONS = Arrays.asList(
192310b7d14546c8f5e49f5e99475fb6001331ac4caMarc R. Hoffmann			DESTFILE, APPEND, INCLUDES, EXCLUDES, EXCLCLASSLOADER,
19326daee44414eeecb0a7a63d7f6784fcf4cfe32faMarc R. Hoffmann			INCLBOOTSTRAPCLASSES, INCLNOLOCATIONCLASSES, SESSIONID, DUMPONEXIT,
19426daee44414eeecb0a7a63d7f6784fcf4cfe32faMarc R. Hoffmann			OUTPUT, ADDRESS, PORT, CLASSDUMPDIR, JMX);
195e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
196e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	private final Map<String, String> options;
197e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
198e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
199e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * New instance with all values set to default.
200e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
201e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public AgentOptions() {
202e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		this.options = new HashMap<String, String>();
203e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
204e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
205e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
206e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * New instance parsed from the given option string.
207e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *
208e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @param optionstr
209e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *            string to parse or <code>null</code>
210e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
211e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public AgentOptions(final String optionstr) {
212e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		this();
213e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		if (optionstr != null && optionstr.length() > 0) {
214310ceffbcc17605116409cec60a67a2dc3de65b4jochenberger			for (final String entry : OPTION_SPLIT.split(optionstr)) {
215e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov				final int pos = entry.indexOf('=');
216e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov				if (pos == -1) {
217e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov					throw new IllegalArgumentException(format(
218e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov							"Invalid agent option syntax \"%s\".", optionstr));
219e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov				}
220e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov				final String key = entry.substring(0, pos);
221e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov				if (!VALID_OPTIONS.contains(key)) {
222e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov					throw new IllegalArgumentException(format(
223e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov							"Unknown agent option \"%s\".", key));
224e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov				}
225e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
226e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov				final String value = entry.substring(pos + 1);
227e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov				setOption(key, value);
228e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov			}
229e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
230e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov			validateAll();
231e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		}
232e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
233e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
23425fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann	/**
23547990a4a02bb738eedd7dce6a2f2dd10d5f28cc4Marc R. Hoffmann	 * New instance read from the given {@link Properties} object.
23625fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann	 *
23725fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann	 * @param properties
23825fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann	 *            {@link Properties} object to read configuration options from
23925fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann	 */
24025fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann	public AgentOptions(final Properties properties) {
24125fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann		this();
24225fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann		for (final String key : VALID_OPTIONS) {
24347990a4a02bb738eedd7dce6a2f2dd10d5f28cc4Marc R. Hoffmann			final String value = properties.getProperty(key);
24425fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann			if (value != null) {
24525fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann				setOption(key, value);
24625fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann			}
24725fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann		}
24825fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann	}
24925fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann
250e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	private void validateAll() {
251e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		validatePort(getPort());
252e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		getOutput();
253e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
254e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
255e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	private void validatePort(final int port) {
256e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		if (port < 0) {
257e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov			throw new IllegalArgumentException("port must be positive");
258e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		}
259e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
260e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
261e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
262e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Returns the output file location.
263e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *
264e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @return output file location
265e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
266e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public String getDestfile() {
267d5946166388e92f67220bbece1f104e21ab7b0cbMarc R. Hoffmann		return getOption(DESTFILE, DEFAULT_DESTFILE);
268e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
269e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
270e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
271e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Sets the output file location.
272e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *
273e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @param destfile
274e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *            output file location
275e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
276e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public void setDestfile(final String destfile) {
277e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		setOption(DESTFILE, destfile);
278e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
279e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
280e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
281e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Returns whether the output should be appended to an existing file.
282e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *
283e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @return <code>true</code>, when the output should be appended
284e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
285e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public boolean getAppend() {
286e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		return getOption(APPEND, true);
287e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
288e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
289e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
290e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Sets whether the output should be appended to an existing file.
291e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *
292e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @param append
293e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *            <code>true</code>, when the output should be appended
294e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
295e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public void setAppend(final boolean append) {
296e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		setOption(APPEND, append);
297e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
298e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
299e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
300e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Returns the wildcard expression for classes to include.
301e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *
302e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @return wildcard expression for classes to include
303e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @see WildcardMatcher
304e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
305e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public String getIncludes() {
306e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		return getOption(INCLUDES, "*");
307e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
308e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
309e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
310e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Sets the wildcard expression for classes to include.
311e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *
312e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @param includes
313e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *            wildcard expression for classes to include
314e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @see WildcardMatcher
315e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
316e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public void setIncludes(final String includes) {
317e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		setOption(INCLUDES, includes);
318e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
319e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
320e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
321e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Returns the wildcard expression for classes to exclude.
322e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *
323e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @return wildcard expression for classes to exclude
324e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @see WildcardMatcher
325e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
326e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public String getExcludes() {
327e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		return getOption(EXCLUDES, "");
328e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
329e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
330e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
331e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Sets the wildcard expression for classes to exclude.
332e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *
333e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @param excludes
334e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *            wildcard expression for classes to exclude
335e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @see WildcardMatcher
336e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
337e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public void setExcludes(final String excludes) {
338e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		setOption(EXCLUDES, excludes);
339e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
340e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
341e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
342e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Returns the wildcard expression for excluded class loaders.
343e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *
344e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @return expression for excluded class loaders
345e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @see WildcardMatcher
346e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
347e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public String getExclClassloader() {
348e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		return getOption(EXCLCLASSLOADER, "sun.reflect.DelegatingClassLoader");
349e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
350e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
351e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
352e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Sets the wildcard expression for excluded class loaders.
353e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *
354e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @param expression
355e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *            expression for excluded class loaders
356e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @see WildcardMatcher
357e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
358e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public void setExclClassloader(final String expression) {
359e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		setOption(EXCLCLASSLOADER, expression);
360e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
361e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
362e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
363310b7d14546c8f5e49f5e99475fb6001331ac4caMarc R. Hoffmann	 * Returns whether classes from the bootstrap classloader should be
364310b7d14546c8f5e49f5e99475fb6001331ac4caMarc R. Hoffmann	 * instrumented.
365310b7d14546c8f5e49f5e99475fb6001331ac4caMarc R. Hoffmann	 *
36626daee44414eeecb0a7a63d7f6784fcf4cfe32faMarc R. Hoffmann	 * @return <code>true</code> if classes from the bootstrap classloader
36726daee44414eeecb0a7a63d7f6784fcf4cfe32faMarc R. Hoffmann	 *         should be instrumented
368310b7d14546c8f5e49f5e99475fb6001331ac4caMarc R. Hoffmann	 */
3691d8389bf86f8a49d31bb5182b3ec1592e2f7289aMarc R. Hoffmann	public boolean getInclBootstrapClasses() {
3701d8389bf86f8a49d31bb5182b3ec1592e2f7289aMarc R. Hoffmann		return getOption(INCLBOOTSTRAPCLASSES, false);
371310b7d14546c8f5e49f5e99475fb6001331ac4caMarc R. Hoffmann	}
372310b7d14546c8f5e49f5e99475fb6001331ac4caMarc R. Hoffmann
373310b7d14546c8f5e49f5e99475fb6001331ac4caMarc R. Hoffmann	/**
374310b7d14546c8f5e49f5e99475fb6001331ac4caMarc R. Hoffmann	 * Sets whether classes from the bootstrap classloader should be
375310b7d14546c8f5e49f5e99475fb6001331ac4caMarc R. Hoffmann	 * instrumented.
376310b7d14546c8f5e49f5e99475fb6001331ac4caMarc R. Hoffmann	 *
3771d8389bf86f8a49d31bb5182b3ec1592e2f7289aMarc R. Hoffmann	 * @param include
378310b7d14546c8f5e49f5e99475fb6001331ac4caMarc R. Hoffmann	 *            <code>true</code> if bootstrap classes should be instrumented
379310b7d14546c8f5e49f5e99475fb6001331ac4caMarc R. Hoffmann	 */
3801d8389bf86f8a49d31bb5182b3ec1592e2f7289aMarc R. Hoffmann	public void setInclBootstrapClasses(final boolean include) {
3811d8389bf86f8a49d31bb5182b3ec1592e2f7289aMarc R. Hoffmann		setOption(INCLBOOTSTRAPCLASSES, include);
382310b7d14546c8f5e49f5e99475fb6001331ac4caMarc R. Hoffmann	}
383310b7d14546c8f5e49f5e99475fb6001331ac4caMarc R. Hoffmann
384310b7d14546c8f5e49f5e99475fb6001331ac4caMarc R. Hoffmann	/**
38526daee44414eeecb0a7a63d7f6784fcf4cfe32faMarc R. Hoffmann	 * Returns whether classes without source location should be instrumented.
38626daee44414eeecb0a7a63d7f6784fcf4cfe32faMarc R. Hoffmann	 *
38726daee44414eeecb0a7a63d7f6784fcf4cfe32faMarc R. Hoffmann	 * @return <code>true</code> if classes without source location should be
38826daee44414eeecb0a7a63d7f6784fcf4cfe32faMarc R. Hoffmann	 *         instrumented
38926daee44414eeecb0a7a63d7f6784fcf4cfe32faMarc R. Hoffmann	 */
39026daee44414eeecb0a7a63d7f6784fcf4cfe32faMarc R. Hoffmann	public boolean getInclNoLocationClasses() {
39126daee44414eeecb0a7a63d7f6784fcf4cfe32faMarc R. Hoffmann		return getOption(INCLNOLOCATIONCLASSES, false);
39226daee44414eeecb0a7a63d7f6784fcf4cfe32faMarc R. Hoffmann	}
39326daee44414eeecb0a7a63d7f6784fcf4cfe32faMarc R. Hoffmann
39426daee44414eeecb0a7a63d7f6784fcf4cfe32faMarc R. Hoffmann	/**
39526daee44414eeecb0a7a63d7f6784fcf4cfe32faMarc R. Hoffmann	 * Sets whether classes without source location should be instrumented.
39626daee44414eeecb0a7a63d7f6784fcf4cfe32faMarc R. Hoffmann	 *
39726daee44414eeecb0a7a63d7f6784fcf4cfe32faMarc R. Hoffmann	 * @param include
39826daee44414eeecb0a7a63d7f6784fcf4cfe32faMarc R. Hoffmann	 *            <code>true</code> if classes without source location should be
39926daee44414eeecb0a7a63d7f6784fcf4cfe32faMarc R. Hoffmann	 *            instrumented
40026daee44414eeecb0a7a63d7f6784fcf4cfe32faMarc R. Hoffmann	 */
40126daee44414eeecb0a7a63d7f6784fcf4cfe32faMarc R. Hoffmann	public void setInclNoLocationClasses(final boolean include) {
40226daee44414eeecb0a7a63d7f6784fcf4cfe32faMarc R. Hoffmann		setOption(INCLNOLOCATIONCLASSES, include);
40326daee44414eeecb0a7a63d7f6784fcf4cfe32faMarc R. Hoffmann	}
40426daee44414eeecb0a7a63d7f6784fcf4cfe32faMarc R. Hoffmann
40526daee44414eeecb0a7a63d7f6784fcf4cfe32faMarc R. Hoffmann	/**
406e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Returns the session identifier.
407e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *
408e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @return session identifier
409e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
410e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public String getSessionId() {
411e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		return getOption(SESSIONID, null);
412e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
413e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
414e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
415e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Sets the session identifier.
416e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *
417e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @param id
418e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *            session identifier
419e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
420e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public void setSessionId(final String id) {
421e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		setOption(SESSIONID, id);
422e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
423e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
424e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
425310b7d14546c8f5e49f5e99475fb6001331ac4caMarc R. Hoffmann	 * Returns whether coverage data should be dumped on exit.
426e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *
427e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @return <code>true</code> if coverage data will be written on VM exit
428e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
429e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public boolean getDumpOnExit() {
430e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		return getOption(DUMPONEXIT, true);
431e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
432e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
433e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
434310b7d14546c8f5e49f5e99475fb6001331ac4caMarc R. Hoffmann	 * Sets whether coverage data should be dumped on exit.
435e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *
436e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @param dumpOnExit
437e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *            <code>true</code> if coverage data should be written on VM
438e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *            exit
439e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
440e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public void setDumpOnExit(final boolean dumpOnExit) {
441e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		setOption(DUMPONEXIT, dumpOnExit);
442e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
443e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
444e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
445e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Returns the port on which to listen to when the output is
446e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * <code>tcpserver</code> or the port to connect to when output is
447e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * <code>tcpclient</code>.
448e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *
449e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @return port to listen on or connect to
450e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
451e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public int getPort() {
452e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		return getOption(PORT, DEFAULT_PORT);
453e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
454e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
455e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
456e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Sets the port on which to listen to when output is <code>tcpserver</code>
457e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * or the port to connect to when output is <code>tcpclient</code>
458e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *
459e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @param port
46057f7cf06888f1e34f9ab2e3129c3d433826ecbe1Marc R. Hoffmann	 *            port to listen on or connect to
461e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
462e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public void setPort(final int port) {
463e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		validatePort(port);
464e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		setOption(PORT, port);
465e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
466e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
467e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
468e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Gets the hostname or IP address to listen to when output is
469e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * <code>tcpserver</code> or connect to when output is
470e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * <code>tcpclient</code>
471e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *
472e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @return Hostname or IP address
473e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
474e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public String getAddress() {
475e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		return getOption(ADDRESS, DEFAULT_ADDRESS);
476e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
477e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
478e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
479e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Sets the hostname or IP address to listen to when output is
48057f7cf06888f1e34f9ab2e3129c3d433826ecbe1Marc R. Hoffmann	 * <code>tcpserver</code> or connect to when output is
48157f7cf06888f1e34f9ab2e3129c3d433826ecbe1Marc R. Hoffmann	 * <code>tcpclient</code>
482e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *
483e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @param address
484e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *            Hostname or IP address
485e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
486e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public void setAddress(final String address) {
487e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		setOption(ADDRESS, address);
488e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
489e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
490e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
491e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Returns the output mode
492e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *
493e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @return current output mode
494e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
495e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public OutputMode getOutput() {
496e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		final String value = options.get(OUTPUT);
4976d4519ee213c86ad9f3987e557f7787920a03714Allen Hair// BEGIN android-change
4986d4519ee213c86ad9f3987e557f7787920a03714Allen Hair//		return value == null ? OutputMode.file : OutputMode.valueOf(value);
4996d4519ee213c86ad9f3987e557f7787920a03714Allen Hair		return value == null ? OutputMode.none : OutputMode.valueOf(value);
5006d4519ee213c86ad9f3987e557f7787920a03714Allen Hair// END android-change
501e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
502e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
503e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
504e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Sets the output mode
505e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *
506e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @param output
507e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *            Output mode
508e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
509e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public void setOutput(final String output) {
510e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		setOutput(OutputMode.valueOf(output));
511e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
512e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
513e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
514e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Sets the output mode
515e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *
516e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @param output
517e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *            Output mode
518e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
519e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public void setOutput(final OutputMode output) {
520e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		setOption(OUTPUT, output.name());
521e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
522e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
523e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
524e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Returns the location of the directory where class files should be dumped
525e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * to.
526e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *
527e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @return dump location or <code>null</code> (no dumps)
528e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
529e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public String getClassDumpDir() {
530e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		return getOption(CLASSDUMPDIR, null);
531e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
532e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
533e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
534e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Sets the directory where class files should be dumped to.
535e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *
536e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @param location
537e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *            dump location or <code>null</code> (no dumps)
538e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
539e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public void setClassDumpDir(final String location) {
540e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		setOption(CLASSDUMPDIR, location);
541e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
542e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
543e2930e70cc2d5409732639f0bda3af36b27e6db4Marc R. Hoffmann	/**
544e2930e70cc2d5409732639f0bda3af36b27e6db4Marc R. Hoffmann	 * Returns whether the agent exposes functionality via JMX.
545e2930e70cc2d5409732639f0bda3af36b27e6db4Marc R. Hoffmann	 *
546e2930e70cc2d5409732639f0bda3af36b27e6db4Marc R. Hoffmann	 * @return <code>true</code>, when JMX is enabled
547e2930e70cc2d5409732639f0bda3af36b27e6db4Marc R. Hoffmann	 */
548e2930e70cc2d5409732639f0bda3af36b27e6db4Marc R. Hoffmann	public boolean getJmx() {
549e2930e70cc2d5409732639f0bda3af36b27e6db4Marc R. Hoffmann		return getOption(JMX, false);
550e2930e70cc2d5409732639f0bda3af36b27e6db4Marc R. Hoffmann	}
551e2930e70cc2d5409732639f0bda3af36b27e6db4Marc R. Hoffmann
552e2930e70cc2d5409732639f0bda3af36b27e6db4Marc R. Hoffmann	/**
553f2450ec546d7fd07bf75047f7a4181f9ccc5a585Marc R. Hoffmann	 * Sets whether the agent should expose functionality via JMX.
554e2930e70cc2d5409732639f0bda3af36b27e6db4Marc R. Hoffmann	 *
555e2930e70cc2d5409732639f0bda3af36b27e6db4Marc R. Hoffmann	 * @param jmx
556e2930e70cc2d5409732639f0bda3af36b27e6db4Marc R. Hoffmann	 *            <code>true</code> if JMX should be enabled
557e2930e70cc2d5409732639f0bda3af36b27e6db4Marc R. Hoffmann	 */
558e2930e70cc2d5409732639f0bda3af36b27e6db4Marc R. Hoffmann	public void setJmx(final boolean jmx) {
559e2930e70cc2d5409732639f0bda3af36b27e6db4Marc R. Hoffmann		setOption(JMX, jmx);
560e2930e70cc2d5409732639f0bda3af36b27e6db4Marc R. Hoffmann	}
561e2930e70cc2d5409732639f0bda3af36b27e6db4Marc R. Hoffmann
562e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	private void setOption(final String key, final int value) {
563e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		setOption(key, Integer.toString(value));
564e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
565e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
566e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	private void setOption(final String key, final boolean value) {
567e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		setOption(key, Boolean.toString(value));
568e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
569e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
570e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	private void setOption(final String key, final String value) {
571e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		options.put(key, value);
572e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
573e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
574e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	private String getOption(final String key, final String defaultValue) {
575e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		final String value = options.get(key);
576e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		return value == null ? defaultValue : value;
577e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
578e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
579e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	private boolean getOption(final String key, final boolean defaultValue) {
580e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		final String value = options.get(key);
581e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		return value == null ? defaultValue : Boolean.parseBoolean(value);
582e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
583e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
584e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	private int getOption(final String key, final int defaultValue) {
585e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		final String value = options.get(key);
586e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		return value == null ? defaultValue : Integer.parseInt(value);
587e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
588e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
589e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
5909fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann	 * Generate required JVM argument based on current configuration and
5919fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann	 * supplied agent jar location.
592e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *
593e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @param agentJarFile
594e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *            location of the JaCoCo Agent Jar
595e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @return Argument to pass to create new VM with coverage enabled
596e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
597e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public String getVMArgument(final File agentJarFile) {
598e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		return format("-javaagent:%s=%s", agentJarFile, this);
599e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
600e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
601e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
6029fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann	 * Generate required quoted JVM argument based on current configuration and
6039fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann	 * supplied agent jar location.
6049fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann	 *
6059fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann	 * @param agentJarFile
6069fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann	 *            location of the JaCoCo Agent Jar
6079fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann	 * @return Quoted argument to pass to create new VM with coverage enabled
6089fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann	 */
6099fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann	public String getQuotedVMArgument(final File agentJarFile) {
6109fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann		return CommandLineSupport.quote(getVMArgument(agentJarFile));
6119fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann	}
6129fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann
6139fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann	/**
6149fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann	 * Generate required quotes JVM argument based on current configuration and
6159fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann	 * prepends it to the given argument command line. If a agent with the same
6169fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann	 * JAR file is already specified this parameter is removed from the existing
6179fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann	 * command line.
6189fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann	 *
6199fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann	 * @param arguments
6209fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann	 *            existing command line arguments or <code>null</code>
6219fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann	 * @param agentJarFile
6229fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann	 *            location of the JaCoCo Agent Jar
6239fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann	 * @return VM command line arguments prepended with configured JaCoCo agent
6249fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann	 */
6259fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann	public String prependVMArguments(final String arguments,
6269fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann			final File agentJarFile) {
6279fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann		final List<String> args = CommandLineSupport.split(arguments);
6289fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann		final String plainAgent = format("-javaagent:%s", agentJarFile);
6299fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann		for (final Iterator<String> i = args.iterator(); i.hasNext();) {
6309fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann			if (i.next().startsWith(plainAgent)) {
6319fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann				i.remove();
6329fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann			}
6339fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann		}
6349fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann		args.add(0, getVMArgument(agentJarFile));
6359fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann		return CommandLineSupport.quote(args);
6369fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann	}
6379fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann
6389fdd14bd5cf0ad765135c8466dcaa9921c72c74bMarc R. Hoffmann	/**
639e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Creates a string representation that can be passed to the agent via the
640e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * command line. Might be the empty string, if no options are set.
641e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
642e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	@Override
643e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	public String toString() {
644e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		final StringBuilder sb = new StringBuilder();
645e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		for (final String key : VALID_OPTIONS) {
646e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov			final String value = options.get(key);
647e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov			if (value != null) {
648e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov				if (sb.length() > 0) {
649e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov					sb.append(',');
650e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov				}
651e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov				sb.append(key).append('=').append(value);
652e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov			}
653e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		}
654e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		return sb.toString();
655e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
656e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
657e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov}
658