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