Home | History | Annotate | Download | only in maven
      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  *    Evgeny Mandrikov - initial API and implementation
     10  *
     11  *******************************************************************************/
     12 package org.jacoco.maven;
     13 
     14 import java.io.File;
     15 import java.io.FileInputStream;
     16 import java.io.FileOutputStream;
     17 import java.io.IOException;
     18 import java.io.InputStream;
     19 import java.io.OutputStream;
     20 import java.util.List;
     21 
     22 import org.apache.maven.plugin.MojoExecutionException;
     23 import org.apache.maven.plugin.MojoFailureException;
     24 import org.codehaus.plexus.util.FileUtils;
     25 import org.codehaus.plexus.util.IOUtil;
     26 import org.jacoco.core.instr.Instrumenter;
     27 import org.jacoco.core.runtime.OfflineInstrumentationAccessGenerator;
     28 
     29 /**
     30  * Performs offline instrumentation. Note that after execution of test you must
     31  * restore original classes with help of "restore-instrumented-classes" goal.
     32  * <p>
     33  * <strong>Warning:</strong> The preferred way for code coverage analysis with
     34  * JaCoCo is on-the-fly instrumentation. Offline instrumentation has several
     35  * drawbacks and should only be used if a specific scenario explicitly requires
     36  * this mode. Please consult <a href="offline.html">documentation</a> about
     37  * offline instrumentation before using this mode.
     38  * </p>
     39  *
     40  * @phase process-classes
     41  * @goal instrument
     42  * @requiresProject true
     43  * @threadSafe
     44  * @since 0.6.2
     45  */
     46 public class InstrumentMojo extends AbstractJacocoMojo {
     47 
     48 	@Override
     49 	public void executeMojo() throws MojoExecutionException,
     50 			MojoFailureException {
     51 		final File originalClassesDir = new File(getProject().getBuild()
     52 				.getDirectory(), "generated-classes/jacoco");
     53 		originalClassesDir.mkdirs();
     54 		final File classesDir = new File(
     55 				getProject().getBuild().getOutputDirectory());
     56 		if (!classesDir.exists()) {
     57 			getLog().info(
     58 					"Skipping JaCoCo execution due to missing classes directory:" +
     59 					classesDir);
     60 			return;
     61 		}
     62 
     63 		final List<String> fileNames;
     64 		try {
     65 			fileNames = new FileFilter(this.getIncludes(), this.getExcludes())
     66 					.getFileNames(classesDir);
     67 		} catch (final IOException e1) {
     68 			throw new MojoExecutionException(
     69 					"Unable to get list of files to instrument.", e1);
     70 		}
     71 
     72 		final Instrumenter instrumenter = new Instrumenter(
     73 				new OfflineInstrumentationAccessGenerator());
     74 		for (final String fileName : fileNames) {
     75 			if (fileName.endsWith(".class")) {
     76 				final File source = new File(classesDir, fileName);
     77 				final File backup = new File(originalClassesDir, fileName);
     78 				InputStream input = null;
     79 				OutputStream output = null;
     80 				try {
     81 					FileUtils.copyFile(source, backup);
     82 					input = new FileInputStream(backup);
     83 					output = new FileOutputStream(source);
     84 					instrumenter.instrument(input, output, source.getPath());
     85 				} catch (final IOException e2) {
     86 					throw new MojoExecutionException(
     87 							"Unable to instrument file.", e2);
     88 				} finally {
     89 					IOUtil.close(input);
     90 					IOUtil.close(output);
     91 				}
     92 			}
     93 		}
     94 	}
     95 
     96 }
     97