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 *******************************************************************************/
12ae1034c608eeca9765a43bec34bcb8e5bf23eaffMarc R. Hoffmannpackage org.jacoco.agent.rt.internal;
13e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
142a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmannimport java.io.ByteArrayOutputStream;
152a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmannimport java.io.IOException;
16e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikovimport java.net.InetAddress;
17b887be401ea77008a62390149962714fd66c6ad6Marc R. Hoffmannimport java.util.concurrent.Callable;
18e2930e70cc2d5409732639f0bda3af36b27e6db4Marc R. Hoffmann
192a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmannimport org.jacoco.agent.rt.IAgent;
2082608019c1e03552fc80df7f70e7f7c5270a0637Marc R. Hoffmannimport org.jacoco.agent.rt.internal.output.FileOutput;
2182608019c1e03552fc80df7f70e7f7c5270a0637Marc R. Hoffmannimport org.jacoco.agent.rt.internal.output.IAgentOutput;
2282608019c1e03552fc80df7f70e7f7c5270a0637Marc R. Hoffmannimport org.jacoco.agent.rt.internal.output.NoneOutput;
2382608019c1e03552fc80df7f70e7f7c5270a0637Marc R. Hoffmannimport org.jacoco.agent.rt.internal.output.TcpClientOutput;
2482608019c1e03552fc80df7f70e7f7c5270a0637Marc R. Hoffmannimport org.jacoco.agent.rt.internal.output.TcpServerOutput;
252a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmannimport org.jacoco.core.JaCoCo;
262a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmannimport org.jacoco.core.data.ExecutionDataWriter;
27e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikovimport org.jacoco.core.runtime.AbstractRuntime;
28e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikovimport org.jacoco.core.runtime.AgentOptions;
29e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikovimport org.jacoco.core.runtime.AgentOptions.OutputMode;
3027e32e433ba0ac1fdec9290d3454d5b369c969ccMarc R. Hoffmannimport org.jacoco.core.runtime.RuntimeData;
31e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
32e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov/**
3325fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann * The agent manages the life cycle of JaCoCo runtime.
34e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov */
352a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmannpublic class Agent implements IAgent {
3625fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann
3725fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann	private static Agent singleton;
3825fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann
3925fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann	/**
4025fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann	 * Returns a global instance which is already started. If the method is
4125fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann	 * called the first time the instance is created with the given options.
4225fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann	 *
4325fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann	 * @param options
4425fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann	 *            options to configure the instance
4525fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann	 * @return global instance
4625fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann	 */
47ad8749dace1130caf442704d302e178dd29089b7Marc R. Hoffmann	public static synchronized Agent getInstance(final AgentOptions options) {
4804f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin		// BEGIN android-change
4904f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin		return getInstance(options, new RuntimeData());
5004f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin		// END android-change
5104f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin	}
5204f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin
5304f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin	// BEGIN android-change
5404f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin	/**
5504f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin	 * Returns a global instance which is already started, reusing an existing set of runtime
5604f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin	 * data. If the method is called the first time the instance is created with the given
5704f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin	 * options.
5804f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin	 *
5904f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin	 * @param options
6004f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin	 *            options to configure the instance
6104f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin	 * @param data
6204f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin	 *            the runtime data to reuse
6304f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin	 * @return global instance
6404f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin	 */
6504f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin	public static synchronized Agent getInstance(final AgentOptions options, RuntimeData data) {
6625fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann		if (singleton == null) {
6704f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin			final Agent agent = new Agent(options, IExceptionLogger.SYSTEM_ERR, data);
6825fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann			agent.startup();
6925fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann			Runtime.getRuntime().addShutdownHook(new Thread() {
7025fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann				@Override
7125fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann				public void run() {
7225fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann					agent.shutdown();
7325fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann				}
7425fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann			});
7525fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann			singleton = agent;
7625fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann		}
7725fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann		return singleton;
7825fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann	}
7904f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin	// END android-change
80e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
8104f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin	// BEGIN android-change
822a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann	/**
8304f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin	 * Returns a global instance which is already started. If an agent has not
8404f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin	 * been initialized then one will be created via {@link Offline#createAgent()}.
856c3ded30e516793d3bdfdead872ceb3700be8453Pete Gillin	 * This will capture any data written via {@link Offline#getProbes} prior to
866c3ded30e516793d3bdfdead872ceb3700be8453Pete Gillin	 * this call, but not subsequently.
872a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann	 *
882a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann	 * @return global instance
892a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann	 * @throws IllegalStateException
902a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann	 *             if no Agent has been started yet
912a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann	 */
9204f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin	// END android-change
932a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann	public static synchronized Agent getInstance() throws IllegalStateException {
942a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann		if (singleton == null) {
9504f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin			// BEGIN android-change
9604f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin			// throw new IllegalStateException("JaCoCo agent not started.");
9704f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin			singleton = Offline.createAgent();
9804f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin			// END android-change
992a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann		}
1002a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann		return singleton;
1012a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann	}
1022a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann
103e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	private final AgentOptions options;
104e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
105e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	private final IExceptionLogger logger;
106e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
107b887be401ea77008a62390149962714fd66c6ad6Marc R. Hoffmann	private final RuntimeData data;
108b887be401ea77008a62390149962714fd66c6ad6Marc R. Hoffmann
10982608019c1e03552fc80df7f70e7f7c5270a0637Marc R. Hoffmann	private IAgentOutput output;
110e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
111b887be401ea77008a62390149962714fd66c6ad6Marc R. Hoffmann	private Callable<Void> jmxRegistration;
11225fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann
113e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
114e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Creates a new agent with the given agent options.
115e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *
116e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @param options
117e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *            agent options
118e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @param logger
119e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *            logger used by this agent
120e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
1217d5960fd5978d820c70d02ef6563ca0b9ffb872dMarc R. Hoffmann	Agent(final AgentOptions options, final IExceptionLogger logger) {
12204f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin		// BEGIN android-change
12304f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin		this(options, logger, new RuntimeData());
12404f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin		// END android-change
12504f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin	}
12604f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin
12704f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin	// BEGIN android-change
12804f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin	/**
12904f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin	 * Creates a new agent with the given agent options, reusing the given runtime data.
13004f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin	 *
13104f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin	 * @param options
13204f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin	 *            agent options
13304f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin	 * @param logger
13404f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin	 *            logger used by this agent
13504f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin	 * @param data
13604f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin	 *            the runtime data to reuse
13704f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin	 */
13804f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin	private Agent(final AgentOptions options, final IExceptionLogger logger, RuntimeData data) {
139e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		this.options = options;
140e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		this.logger = logger;
14104f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin		this.data = data;
142e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
14304f25e91a87fb5314e2e7ad979641dd453e43ddaPete Gillin	// END android-change
144e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
145e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
14625fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann	 * Returns the runtime data object created by this agent
147e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *
14825fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann	 * @return runtime data for this agent instance
149e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
15025fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann	public RuntimeData getData() {
15125fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann		return data;
152e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
153e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
154e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
155e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * Initializes this agent.
156e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *
157e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
158ad8749dace1130caf442704d302e178dd29089b7Marc R. Hoffmann	public void startup() {
159ad8749dace1130caf442704d302e178dd29089b7Marc R. Hoffmann		try {
160ad8749dace1130caf442704d302e178dd29089b7Marc R. Hoffmann			String sessionId = options.getSessionId();
161ad8749dace1130caf442704d302e178dd29089b7Marc R. Hoffmann			if (sessionId == null) {
162ad8749dace1130caf442704d302e178dd29089b7Marc R. Hoffmann				sessionId = createSessionId();
163ad8749dace1130caf442704d302e178dd29089b7Marc R. Hoffmann			}
164ad8749dace1130caf442704d302e178dd29089b7Marc R. Hoffmann			data.setSessionId(sessionId);
16582608019c1e03552fc80df7f70e7f7c5270a0637Marc R. Hoffmann			output = createAgentOutput();
16682608019c1e03552fc80df7f70e7f7c5270a0637Marc R. Hoffmann			output.startup(options, data);
167e2930e70cc2d5409732639f0bda3af36b27e6db4Marc R. Hoffmann			if (options.getJmx()) {
1688d9dc829193712ce6859dbd1b894fa2fe6545ff8Sebastien Hertz// BEGIN android-change
1698d9dc829193712ce6859dbd1b894fa2fe6545ff8Sebastien Hertz//				jmxRegistration = new JmxRegistration(this);
1708d9dc829193712ce6859dbd1b894fa2fe6545ff8Sebastien Hertz// END android-change
171e2930e70cc2d5409732639f0bda3af36b27e6db4Marc R. Hoffmann			}
172ad8749dace1130caf442704d302e178dd29089b7Marc R. Hoffmann		} catch (final Exception e) {
173ad8749dace1130caf442704d302e178dd29089b7Marc R. Hoffmann			logger.logExeption(e);
174e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		}
175e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
176e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
177e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	/**
17825fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann	 * Shutdown the agent again.
17925fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann	 */
18025fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann	public void shutdown() {
18125fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann		try {
18225fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann			if (options.getDumpOnExit()) {
18382608019c1e03552fc80df7f70e7f7c5270a0637Marc R. Hoffmann				output.writeExecutionData(false);
18425fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann			}
18582608019c1e03552fc80df7f70e7f7c5270a0637Marc R. Hoffmann			output.shutdown();
186b887be401ea77008a62390149962714fd66c6ad6Marc R. Hoffmann			if (jmxRegistration != null) {
187b887be401ea77008a62390149962714fd66c6ad6Marc R. Hoffmann				jmxRegistration.call();
188e2930e70cc2d5409732639f0bda3af36b27e6db4Marc R. Hoffmann			}
18925fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann		} catch (final Exception e) {
19025fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann			logger.logExeption(e);
19125fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann		}
19225fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann	}
19325fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann
19425fb3d4e2bac150627f091d310bafb6be465f37bMarc R. Hoffmann	/**
19582608019c1e03552fc80df7f70e7f7c5270a0637Marc R. Hoffmann	 * Create output implementation as given by the agent options.
196e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 *
197e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 * @return configured controller implementation
198e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	 */
19982608019c1e03552fc80df7f70e7f7c5270a0637Marc R. Hoffmann	IAgentOutput createAgentOutput() {
200e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		final OutputMode controllerType = options.getOutput();
201e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		switch (controllerType) {
202e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		case file:
20382608019c1e03552fc80df7f70e7f7c5270a0637Marc R. Hoffmann			return new FileOutput();
204e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		case tcpserver:
20582608019c1e03552fc80df7f70e7f7c5270a0637Marc R. Hoffmann			return new TcpServerOutput(logger);
206e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		case tcpclient:
20782608019c1e03552fc80df7f70e7f7c5270a0637Marc R. Hoffmann			return new TcpClientOutput(logger);
2088c614bab37eee9dbf920a7b20a2b18ab1b8c20d4Evgeny Mandrikov		case none:
20982608019c1e03552fc80df7f70e7f7c5270a0637Marc R. Hoffmann			return new NoneOutput();
210e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		default:
211e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov			throw new AssertionError(controllerType);
212e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		}
213e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
214e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
215e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	private String createSessionId() {
216e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		String host;
217e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		try {
218e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov			host = InetAddress.getLocalHost().getHostName();
21954bf6f1ba2f668019647cf00c48d20929766dfa9Marc R. Hoffmann		} catch (final Exception e) {
22054bf6f1ba2f668019647cf00c48d20929766dfa9Marc R. Hoffmann			// Also catch platform specific exceptions (like on Android) to
22154bf6f1ba2f668019647cf00c48d20929766dfa9Marc R. Hoffmann			// avoid bailing out here
222e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov			host = "unknownhost";
223e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		}
224e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov		return host + "-" + AbstractRuntime.createRandomId();
225e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov	}
226e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov
2272a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann	// === IAgent Implementation ===
2282a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann
2292a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann	public String getVersion() {
2302a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann		return JaCoCo.VERSION;
2312a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann	}
2322a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann
2332a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann	public String getSessionId() {
2342a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann		return data.getSessionId();
2352a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann	}
2362a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann
2372a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann	public void setSessionId(final String id) {
2382a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann		data.setSessionId(id);
2392a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann	}
2402a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann
2412a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann	public void reset() {
2422a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann		data.reset();
2432a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann	}
2442a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann
2452a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann	public byte[] getExecutionData(final boolean reset) {
2462a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann		final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
2472a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann		try {
2482a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann			final ExecutionDataWriter writer = new ExecutionDataWriter(buffer);
2492a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann			data.collect(writer, writer, reset);
2502a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann		} catch (final IOException e) {
2512a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann			// Must not happen with ByteArrayOutputStream
2522a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann			throw new AssertionError(e);
2532a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann		}
2542a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann		return buffer.toByteArray();
2552a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann	}
2562a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann
2572a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann	public void dump(final boolean reset) throws IOException {
25882608019c1e03552fc80df7f70e7f7c5270a0637Marc R. Hoffmann		output.writeExecutionData(reset);
2592a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann	}
2602a8b5339c422de268cae3a862a85666a9b0ac176Marc R. Hoffmann
261e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov}
262