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  *    Marc R. Hoffmann - initial API and implementation
10  *
11  *******************************************************************************/
12 package org.jacoco.examples;
13 
14 import java.io.FileOutputStream;
15 import java.io.IOException;
16 import java.net.InetAddress;
17 import java.net.ServerSocket;
18 import java.net.Socket;
19 
20 import org.jacoco.core.data.ExecutionData;
21 import org.jacoco.core.data.ExecutionDataWriter;
22 import org.jacoco.core.data.IExecutionDataVisitor;
23 import org.jacoco.core.data.ISessionInfoVisitor;
24 import org.jacoco.core.data.SessionInfo;
25 import org.jacoco.core.runtime.RemoteControlReader;
26 import org.jacoco.core.runtime.RemoteControlWriter;
27 
28 /**
29  * This example starts a socket server to collect coverage from agents that run
30  * in output mode <code>tcpclient</code>. The collected data is dumped to a
31  * local file.
32  */
33 public final class ExecutionDataServer {
34 
35 	private static final String DESTFILE = "jacoco-server.exec";
36 
37 	private static final String ADDRESS = "localhost";
38 
39 	private static final int PORT = 6300;
40 
41 	/**
42 	 * Start the server as a standalone program.
43 	 *
44 	 * @param args
45 	 * @throws IOException
46 	 */
main(final String[] args)47 	public static void main(final String[] args) throws IOException {
48 		final ExecutionDataWriter fileWriter = new ExecutionDataWriter(
49 				new FileOutputStream(DESTFILE));
50 		final ServerSocket server = new ServerSocket(PORT, 0,
51 				InetAddress.getByName(ADDRESS));
52 		while (true) {
53 			final Handler handler = new Handler(server.accept(), fileWriter);
54 			new Thread(handler).start();
55 		}
56 	}
57 
58 	private static class Handler implements Runnable, ISessionInfoVisitor,
59 			IExecutionDataVisitor {
60 
61 		private final Socket socket;
62 
63 		private final RemoteControlReader reader;
64 
65 		private final ExecutionDataWriter fileWriter;
66 
Handler(final Socket socket, final ExecutionDataWriter fileWriter)67 		Handler(final Socket socket, final ExecutionDataWriter fileWriter)
68 				throws IOException {
69 			this.socket = socket;
70 			this.fileWriter = fileWriter;
71 
72 			// Just send a valid header:
73 			new RemoteControlWriter(socket.getOutputStream());
74 
75 			reader = new RemoteControlReader(socket.getInputStream());
76 			reader.setSessionInfoVisitor(this);
77 			reader.setExecutionDataVisitor(this);
78 		}
79 
run()80 		public void run() {
81 			try {
82 				while (reader.read()) {
83 				}
84 				socket.close();
85 				synchronized (fileWriter) {
86 					fileWriter.flush();
87 				}
88 			} catch (final IOException e) {
89 				e.printStackTrace();
90 			}
91 		}
92 
visitSessionInfo(final SessionInfo info)93 		public void visitSessionInfo(final SessionInfo info) {
94 			System.out.printf("Retrieving execution Data for session: %s%n",
95 					info.getId());
96 			synchronized (fileWriter) {
97 				fileWriter.visitSessionInfo(info);
98 			}
99 		}
100 
visitClassExecution(final ExecutionData data)101 		public void visitClassExecution(final ExecutionData data) {
102 			synchronized (fileWriter) {
103 				fileWriter.visitClassExecution(data);
104 			}
105 		}
106 	}
107 
ExecutionDataServer()108 	private ExecutionDataServer() {
109 	}
110 }
111