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 *******************************************************************************/
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 0.4.1.20101007204400
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}