1/******************************************************************************* 2 * Copyright (c) 2009, 2017 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 * John Keeping - initial implementation 10 * Marc R. Hoffmann - rework 11 * 12 *******************************************************************************/ 13package org.jacoco.cli.internal.commands; 14 15import java.io.File; 16import java.io.FileInputStream; 17import java.io.FileOutputStream; 18import java.io.IOException; 19import java.io.InputStream; 20import java.io.OutputStream; 21import java.io.PrintWriter; 22import java.util.ArrayList; 23import java.util.List; 24 25import org.jacoco.cli.internal.Command; 26import org.jacoco.core.instr.Instrumenter; 27import org.jacoco.core.runtime.OfflineInstrumentationAccessGenerator; 28import org.kohsuke.args4j.Argument; 29import org.kohsuke.args4j.Option; 30 31/** 32 * The <code>instrument</code> command. 33 */ 34public class Instrument extends Command { 35 36 @Option(name = "-dest", usage = "path to write instrumented Java classes to", metaVar = "<dir>", required = true) 37 File dest; 38 39 @Argument(usage = "list of folder or files to instrument recusively", metaVar = "<sourcefiles>") 40 List<File> source = new ArrayList<File>(); 41 42 private Instrumenter instrumenter; 43 44 @Override 45 public String description() { 46 return "Off-line instrumentation of Java class files and JAR files."; 47 } 48 49 @Override 50 public int execute(final PrintWriter out, final PrintWriter err) 51 throws IOException { 52 instrumenter = new Instrumenter( 53 new OfflineInstrumentationAccessGenerator()); 54 int total = 0; 55 for (final File s : source) { 56 total += instrumentRecursive(s, dest); 57 } 58 out.printf("[INFO] %s classes instrumented to %s.%n", 59 Integer.valueOf(total), dest.getAbsolutePath()); 60 return 0; 61 } 62 63 private int instrumentRecursive(final File src, final File dest) 64 throws IOException { 65 int total = 0; 66 if (src.isDirectory()) { 67 for (final File child : src.listFiles()) { 68 total += instrumentRecursive(child, 69 new File(dest, child.getName())); 70 } 71 } else { 72 total += instrument(src, dest); 73 } 74 return total; 75 } 76 77 private int instrument(final File src, final File dest) throws IOException { 78 dest.getParentFile().mkdirs(); 79 final InputStream input = new FileInputStream(src); 80 try { 81 final OutputStream output = new FileOutputStream(dest); 82 try { 83 return instrumenter.instrumentAll(input, output, 84 src.getAbsolutePath()); 85 } finally { 86 output.close(); 87 } 88 } catch (final IOException e) { 89 dest.delete(); 90 throw e; 91 } finally { 92 input.close(); 93 } 94 } 95 96} 97