Instrumenter.java

    1/*******************************************************************************
    2 * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others
    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 * $Id: $
   12 *******************************************************************************/
   13package org.jacoco.core.instr;
   14
   15import org.jacoco.core.runtime.IRuntime;
   16import org.objectweb.asm.ClassReader;
   17import org.objectweb.asm.ClassVisitor;
   18import org.objectweb.asm.ClassWriter;
   19import org.objectweb.asm.Opcodes;
   20
   21/**
   22 * Several APIs to instrument Java class definitions for coverage tracing.
   23 * 
   24 * @author Marc R. Hoffmann
   25 * @version $Revision: $
   26 */
   27public class Instrumenter {
   28
   29    private final IRuntime runtime;
   30
   31    /**
   32     * Creates a new instance based on the given runtime.
   33     * 
   34     * @param runtime
   35     *            runtime used by the instrumented classes
   36     */
   37    public Instrumenter(final IRuntime runtime) {
   38        this.runtime = runtime;
   39    }
   40
   41    /**
   42     * Creates a ASM adapter for a class with the given id.
   43     * 
   44     * @param classid
   45     *            id of the class calculated with {@link CRC64}
   46     * @param cv
   47     *            next class visitor in the chain
   48     * @return new visitor to write class definition to
   49     */
   50    public ClassVisitor createInstrumentingVisitor(final long classid,
   51            final ClassVisitor cv) {
   52        return new ClassInstrumenter(classid, runtime, cv);
   53    }
   54
   55    /**
   56     * Creates a instrumented version of the given class if possible.
   57     * 
   58     * @param reader
   59     *            definition of the class as ASM reader
   60     * @return instrumented definition or <code>null</code>
   61     * 
   62     */
   63    public byte[] instrument(final ClassReader reader) {
   64
   65        // Don't instrument interfaces
   66        if ((reader.getAccess() & Opcodes.ACC_INTERFACE) != 0) {
   67            return null;
   68        }
   69
   70        final ClassWriter writer = new ClassWriter(reader, 0);
   71        final ClassVisitor visitor = createInstrumentingVisitor(CRC64
   72                .checksum(reader.b), writer);
   73        reader.accept(visitor, ClassReader.EXPAND_FRAMES);
   74        return writer.toByteArray();
   75    }
   76
   77    /**
   78     * Creates a instrumented version of the given class if possible.
   79     * 
   80     * @param buffer
   81     *            definition of the class
   82     * @return instrumented definition or <code>null</code>
   83     * 
   84     */
   85    public byte[] instrument(final byte[] buffer) {
   86        return instrument(new ClassReader(buffer));
   87    }
   88
   89}