aboutsummaryrefslogtreecommitdiff
path: root/org.jacoco.core/src/org/jacoco/core/tools/ExecFileLoader.java
blob: cf7b2e567a0117384055b613e00806953a5fd7d6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*******************************************************************************
 * Copyright (c) 2009, 2019 Mountainminds GmbH & Co. KG and Contributors
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Marc R. Hoffmann - initial API and implementation
 *    
 *******************************************************************************/
package org.jacoco.core.tools;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.jacoco.core.data.ExecutionDataReader;
import org.jacoco.core.data.ExecutionDataStore;
import org.jacoco.core.data.ExecutionDataWriter;
import org.jacoco.core.data.SessionInfoStore;

/**
 * Convenience utility for loading *.exec files into a
 * {@link ExecutionDataStore} and a {@link SessionInfoStore}.
 */
public class ExecFileLoader {

	private final SessionInfoStore sessionInfos;
	private final ExecutionDataStore executionData;

	/**
	 * New instance to combine session infos and execution data from multiple
	 * files.
	 */
	public ExecFileLoader() {
		sessionInfos = new SessionInfoStore();
		executionData = new ExecutionDataStore();
	}

	/**
	 * Reads all data from given input stream.
	 * 
	 * @param stream
	 *            Stream to read data from
	 * @throws IOException
	 *             in case of problems while reading from the stream
	 */
	public void load(final InputStream stream) throws IOException {
		final ExecutionDataReader reader = new ExecutionDataReader(
				new BufferedInputStream(stream));
		reader.setExecutionDataVisitor(executionData);
		reader.setSessionInfoVisitor(sessionInfos);
		reader.read();
	}

	/**
	 * Reads all data from given input stream.
	 * 
	 * @param file
	 *            file to read data from
	 * @throws IOException
	 *             in case of problems while reading from the stream
	 */
	public void load(final File file) throws IOException {
		final InputStream stream = new FileInputStream(file);
		try {
			load(stream);
		} finally {
			stream.close();
		}
	}

	/**
	 * Saves the current content into the given output stream.
	 * 
	 * @param stream
	 *            stream to save content to
	 * @throws IOException
	 *             in case of problems while writing to the stream
	 */
	public void save(final OutputStream stream) throws IOException {
		final ExecutionDataWriter dataWriter = new ExecutionDataWriter(stream);
		sessionInfos.accept(dataWriter);
		executionData.accept(dataWriter);
	}

	/**
	 * Saves the current content into the given file. Parent directories are
	 * created as needed. Also a files system lock is acquired to avoid
	 * concurrent write access.
	 * 
	 * @param file
	 *            file to save content to
	 * @param append
	 *            <code>true</code> if the content should be appended, otherwise
	 *            the file is overwritten.
	 * @throws IOException
	 *             in case of problems while writing to the stream
	 */
	public void save(final File file, final boolean append) throws IOException {
		final File folder = file.getParentFile();
		if (folder != null) {
			folder.mkdirs();
		}
		final FileOutputStream fileStream = new FileOutputStream(file, append);
		// Avoid concurrent writes from other processes:
		fileStream.getChannel().lock();
		final OutputStream bufferedStream = new BufferedOutputStream(fileStream);
		try {
			save(bufferedStream);
		} finally {
			bufferedStream.close();
		}
	}

	/**
	 * Returns the session info store with all loaded sessions.
	 * 
	 * @return session info store
	 */
	public SessionInfoStore getSessionInfoStore() {
		return sessionInfos;
	}

	/**
	 * Returns the execution data store with data for all loaded classes.
	 * 
	 * @return execution data store
	 */
	public ExecutionDataStore getExecutionDataStore() {
		return executionData;
	}

}