Instrumenter.java
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 * $Id: $
12 *******************************************************************************/
13package org.jacoco.core.instr;
14
15import java.io.IOException;
16import java.io.InputStream;
17
18import org.jacoco.core.runtime.IRuntime;
19import org.objectweb.asm.ClassReader;
20import org.objectweb.asm.ClassVisitor;
21import org.objectweb.asm.ClassWriter;
22
23/**
24 * Several APIs to instrument Java class definitions for coverage tracing.
25 *
26 * @author Marc R. Hoffmann
27 * @version $Revision: $
28 */
29public class Instrumenter {
30
31 private final IRuntime runtime;
32
33 /**
34 * Creates a new instance based on the given runtime.
35 *
36 * @param runtime
37 * runtime used by the instrumented classes
38 */
39 public Instrumenter(final IRuntime runtime) {
40 this.runtime = runtime;
41 }
42
43 /**
44 * Creates a ASM adapter for a class with the given id.
45 *
46 * @param classid
47 * id of the class calculated with {@link CRC64}
48 * @param cv
49 * next class visitor in the chain
50 * @return new visitor to write class definition to
51 */
52 public ClassVisitor createInstrumentingVisitor(final long classid,
53 final ClassVisitor cv) {
54 return 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}