Instrumenter.java revision 1b885c7bc666c215c3947ad4d12099273a5f533f
1/******************************************************************************* 2 * Copyright (c) 2009, 2010 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 * Marc R. Hoffmann - initial API and implementation 10 * 11 *******************************************************************************/ 12package org.jacoco.core.instr; 13 14import java.io.IOException; 15import java.io.InputStream; 16 17import org.jacoco.core.runtime.IRuntime; 18import org.objectweb.asm.ClassReader; 19import org.objectweb.asm.ClassVisitor; 20import org.objectweb.asm.ClassWriter; 21 22/** 23 * Several APIs to instrument Java class definitions for coverage tracing. 24 * 25 * @author Marc R. Hoffmann 26 * @version $qualified.bundle.version$ 27 */ 28public class Instrumenter { 29 30 private final IRuntime runtime; 31 32 /** 33 * Creates a new instance based on the given runtime. 34 * 35 * @param runtime 36 * runtime used by the instrumented classes 37 */ 38 public Instrumenter(final IRuntime runtime) { 39 this.runtime = runtime; 40 } 41 42 /** 43 * Creates a ASM adapter for a class with the given id. 44 * 45 * @param classid 46 * id of the class calculated with {@link CRC64} 47 * @param cv 48 * next class visitor in the chain 49 * @return new visitor to write class definition to 50 */ 51 public ClassVisitor createInstrumentingVisitor(final long classid, 52 final ClassVisitor cv) { 53 return new BlockClassAdapter( 54 new ClassInstrumenter(classid, runtime, cv)); 55 } 56 57 /** 58 * Creates a instrumented version of the given class if possible. 59 * 60 * @param reader 61 * definition of the class as ASM reader 62 * @return instrumented definition or <code>null</code> 63 * 64 */ 65 public byte[] instrument(final ClassReader reader) { 66 final ClassWriter writer = new ClassWriter(reader, 0); 67 final ClassVisitor visitor = createInstrumentingVisitor(CRC64 68 .checksum(reader.b), writer); 69 reader.accept(visitor, ClassReader.EXPAND_FRAMES); 70 return writer.toByteArray(); 71 } 72 73 /** 74 * Creates a instrumented version of the given class if possible. 75 * 76 * @param buffer 77 * definition of the class 78 * @return instrumented definition or <code>null</code> 79 * 80 */ 81 public byte[] instrument(final byte[] buffer) { 82 return instrument(new ClassReader(buffer)); 83 } 84 85 /** 86 * Creates a instrumented version of the given class if possible. 87 * 88 * @param input 89 * stream to read class definition from 90 * @return instrumented definition or <code>null</code> 91 * @throws IOException 92 * if reading data from the stream fails 93 * 94 */ 95 public byte[] instrument(final InputStream input) throws IOException { 96 return instrument(new ClassReader(input)); 97 } 98 99} 100