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.core.tools;
13 
14 import java.io.BufferedInputStream;
15 import java.io.BufferedOutputStream;
16 import java.io.File;
17 import java.io.FileInputStream;
18 import java.io.FileOutputStream;
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.io.OutputStream;
22 
23 import org.jacoco.core.data.ExecutionDataReader;
24 import org.jacoco.core.data.ExecutionDataStore;
25 import org.jacoco.core.data.ExecutionDataWriter;
26 import org.jacoco.core.data.SessionInfoStore;
27 
28 /**
29  * Convenience utility for loading *.exec files into a
30  * {@link ExecutionDataStore} and a {@link SessionInfoStore}.
31  */
32 public class ExecFileLoader {
33 
34 	private final SessionInfoStore sessionInfos;
35 	private final ExecutionDataStore executionData;
36 
37 	/**
38 	 * New instance to combine session infos and execution data from multiple
39 	 * files.
40 	 */
ExecFileLoader()41 	public ExecFileLoader() {
42 		sessionInfos = new SessionInfoStore();
43 		executionData = new ExecutionDataStore();
44 	}
45 
46 	/**
47 	 * Reads all data from given input stream.
48 	 *
49 	 * @param stream
50 	 *            Stream to read data from
51 	 * @throws IOException
52 	 *             in case of problems while reading from the stream
53 	 */
load(final InputStream stream)54 	public void load(final InputStream stream) throws IOException {
55 		final ExecutionDataReader reader = new ExecutionDataReader(
56 				new BufferedInputStream(stream));
57 		reader.setExecutionDataVisitor(executionData);
58 		reader.setSessionInfoVisitor(sessionInfos);
59 		reader.read();
60 	}
61 
62 	/**
63 	 * Reads all data from given input stream.
64 	 *
65 	 * @param file
66 	 *            file to read data from
67 	 * @throws IOException
68 	 *             in case of problems while reading from the stream
69 	 */
load(final File file)70 	public void load(final File file) throws IOException {
71 		final InputStream stream = new FileInputStream(file);
72 		try {
73 			load(stream);
74 		} finally {
75 			stream.close();
76 		}
77 	}
78 
79 	/**
80 	 * Saves the current content into the given output stream.
81 	 *
82 	 * @param stream
83 	 *            stream to save content to
84 	 * @throws IOException
85 	 *             in case of problems while writing to the stream
86 	 */
save(final OutputStream stream)87 	public void save(final OutputStream stream) throws IOException {
88 		final ExecutionDataWriter dataWriter = new ExecutionDataWriter(stream);
89 		sessionInfos.accept(dataWriter);
90 		executionData.accept(dataWriter);
91 	}
92 
93 	/**
94 	 * Saves the current content into the given file. Parent directories are
95 	 * created as needed. Also a files system lock is acquired to avoid
96 	 * concurrent write access.
97 	 *
98 	 * @param file
99 	 *            file to save content to
100 	 * @param append
101 	 *            <code>true</code> if the content should be appended, otherwise
102 	 *            the file is overwritten.
103 	 * @throws IOException
104 	 *             in case of problems while writing to the stream
105 	 */
save(final File file, final boolean append)106 	public void save(final File file, final boolean append) throws IOException {
107 		final File folder = file.getParentFile();
108 		if (folder != null) {
109 			folder.mkdirs();
110 		}
111 		final FileOutputStream fileStream = new FileOutputStream(file, append);
112 		// Avoid concurrent writes from other processes:
113 		fileStream.getChannel().lock();
114 		final OutputStream bufferedStream = new BufferedOutputStream(fileStream);
115 		try {
116 			save(bufferedStream);
117 		} finally {
118 			bufferedStream.close();
119 		}
120 	}
121 
122 	/**
123 	 * Returns the session info store with all loaded sessions.
124 	 *
125 	 * @return session info store
126 	 */
getSessionInfoStore()127 	public SessionInfoStore getSessionInfoStore() {
128 		return sessionInfos;
129 	}
130 
131 	/**
132 	 * Returns the execution data store with data for all loaded classes.
133 	 *
134 	 * @return execution data store
135 	 */
getExecutionDataStore()136 	public ExecutionDataStore getExecutionDataStore() {
137 		return executionData;
138 	}
139 
140 }
141