blob: eb4537bcce424625f3637544bbec9b611198405a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2018 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:
* Brock Janiczak - initial API and implementation
*
*******************************************************************************/
package org.jacoco.ant;
import static java.lang.String.format;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Iterator;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.Resource;
import org.apache.tools.ant.types.ResourceCollection;
import org.apache.tools.ant.types.resources.Union;
import org.apache.tools.ant.util.FileUtils;
import org.jacoco.core.instr.Instrumenter;
import org.jacoco.core.runtime.OfflineInstrumentationAccessGenerator;
/**
* Task for offline instrumentation of class files.
*/
public class InstrumentTask extends Task {
private File destdir;
private final Union files = new Union();
private boolean removesignatures = true;
/**
* Sets the location of the instrumented classes.
*
* @param destdir
* destination folder for instrumented classes
*/
public void setDestdir(final File destdir) {
this.destdir = destdir;
}
/**
* Sets whether signatures should be removed from JAR files.
*
* @param removesignatures
* <code>true</code> if signatures should be removed
*/
public void setRemovesignatures(final boolean removesignatures) {
this.removesignatures = removesignatures;
}
/**
* This task accepts any number of class file resources.
*
* @param resources
* Execution data resources
*/
public void addConfigured(final ResourceCollection resources) {
files.add(resources);
}
@Override
public void execute() throws BuildException {
if (destdir == null) {
throw new BuildException("Destination directory must be supplied",
getLocation());
}
int total = 0;
final Instrumenter instrumenter = new Instrumenter(
new OfflineInstrumentationAccessGenerator());
instrumenter.setRemoveSignatures(removesignatures);
final Iterator<?> resourceIterator = files.iterator();
while (resourceIterator.hasNext()) {
final Resource resource = (Resource) resourceIterator.next();
if (resource.isDirectory()) {
continue;
}
total += instrument(instrumenter, resource);
}
log(format("Instrumented %s classes to %s", Integer.valueOf(total),
destdir.getAbsolutePath()));
}
private int instrument(final Instrumenter instrumenter,
final Resource resource) {
final File file = new File(destdir, resource.getName());
file.getParentFile().mkdirs();
try {
InputStream input = null;
OutputStream output = null;
try {
input = resource.getInputStream();
output = new FileOutputStream(file);
return instrumenter.instrumentAll(input, output,
resource.getName());
} finally {
FileUtils.close(input);
FileUtils.close(output);
}
} catch (final Exception e) {
file.delete();
throw new BuildException(format("Error while instrumenting %s",
resource), e, getLocation());
}
}
}