blob: d79ae62b99c14dc7fe91df85015822db598dbdc0 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2017 Mountainminds GmbH & Co. KG and Contributors
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Evgeny Mandrikov - initial API and implementation
*
*******************************************************************************/
package org.jacoco.core.test;
import java.io.IOException;
import org.jacoco.core.data.ExecutionDataStore;
import org.jacoco.core.data.SessionInfoStore;
import org.jacoco.core.instr.Instrumenter;
import org.jacoco.core.runtime.IRuntime;
import org.jacoco.core.runtime.RuntimeData;
import org.jacoco.core.runtime.SystemPropertiesRuntime;
/**
* Class loader which loads classes from another class loader and instruments
* them.
*/
public final class InstrumentingLoader extends ClassLoader {
private final IRuntime runtime;
private final String scope;
private final ClassLoader delegate;
private final RuntimeData data;
private final Instrumenter instrumenter;
public InstrumentingLoader(IRuntime runtime, String scope,
ClassLoader delegate) throws Exception {
this.runtime = runtime;
this.scope = scope;
this.delegate = delegate;
this.data = new RuntimeData();
runtime.startup(data);
this.instrumenter = new Instrumenter(runtime);
}
public InstrumentingLoader(Class<?> target) throws Exception {
this(new SystemPropertiesRuntime(), target.getPackage().getName(),
target.getClassLoader());
}
@Override
protected synchronized Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException {
if (name.startsWith(scope)) {
final byte[] bytes;
try {
bytes = TargetLoader.getClassDataAsBytes(delegate, name);
} catch (IOException e) {
throw new ClassNotFoundException("Unable to load", e);
}
final byte[] instrumented;
try {
instrumented = instrumenter.instrument(bytes, name);
} catch (IOException e) {
throw new ClassNotFoundException("Unable to instrument", e);
}
final Class<?> c = defineClass(name, instrumented, 0,
instrumented.length);
if (resolve) {
resolveClass(c);
}
return c;
}
return super.loadClass(name, resolve);
}
public ExecutionDataStore collect() {
final ExecutionDataStore store = new ExecutionDataStore();
data.collect(store, new SessionInfoStore(), false);
runtime.shutdown();
return store;
}
}