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 * Brock Janiczak - initial API and implementation 11 * 12 *******************************************************************************/ 13 package org.jacoco.ant; 14 15 import static java.lang.String.format; 16 17 import java.io.File; 18 import java.io.IOException; 19 import java.io.InputStream; 20 import java.util.Iterator; 21 22 import org.apache.tools.ant.BuildException; 23 import org.apache.tools.ant.Task; 24 import org.apache.tools.ant.types.Resource; 25 import org.apache.tools.ant.types.ResourceCollection; 26 import org.apache.tools.ant.types.resources.Union; 27 import org.apache.tools.ant.util.FileUtils; 28 import org.jacoco.core.tools.ExecFileLoader; 29 30 /** 31 * Task for merging a set of execution data files (*.exec) into a single file 32 */ 33 public class MergeTask extends Task { 34 35 private File destfile; 36 37 private final Union files = new Union(); 38 39 /** 40 * Sets the location of the merged data store 41 * 42 * @param destfile 43 * Destination data store location 44 */ setDestfile(final File destfile)45 public void setDestfile(final File destfile) { 46 this.destfile = destfile; 47 } 48 49 /** 50 * This task accepts any number of execution data resources. 51 * 52 * @param resources 53 * Execution data resources 54 */ addConfigured(final ResourceCollection resources)55 public void addConfigured(final ResourceCollection resources) { 56 files.add(resources); 57 } 58 59 @Override execute()60 public void execute() throws BuildException { 61 if (destfile == null) { 62 throw new BuildException("Destination file must be supplied", 63 getLocation()); 64 } 65 66 final ExecFileLoader loader = new ExecFileLoader(); 67 68 load(loader); 69 save(loader); 70 } 71 load(final ExecFileLoader loader)72 private void load(final ExecFileLoader loader) { 73 final Iterator<?> resourceIterator = files.iterator(); 74 while (resourceIterator.hasNext()) { 75 final Resource resource = (Resource) resourceIterator.next(); 76 77 if (resource.isDirectory()) { 78 continue; 79 } 80 81 log(format("Loading execution data file %s", resource)); 82 83 InputStream resourceStream = null; 84 try { 85 resourceStream = resource.getInputStream(); 86 loader.load(resourceStream); 87 } catch (final IOException e) { 88 throw new BuildException(format("Unable to read %s", resource), 89 e, getLocation()); 90 } finally { 91 FileUtils.close(resourceStream); 92 } 93 } 94 } 95 save(final ExecFileLoader loader)96 private void save(final ExecFileLoader loader) { 97 log(format("Writing merged execution data to %s", 98 destfile.getAbsolutePath())); 99 try { 100 loader.save(destfile, false); 101 } catch (final IOException e) { 102 throw new BuildException(format("Unable to write merged file %s", 103 destfile.getAbsolutePath()), e, getLocation()); 104 } 105 } 106 107 } 108