1 /******************************************************************************* 2 * Copyright (c) 2009, 2015 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 *******************************************************************************/ 12 package org.jacoco.core.test; 13 14 import java.io.ByteArrayOutputStream; 15 import java.io.IOException; 16 import java.io.InputStream; 17 import java.util.HashMap; 18 import java.util.Map; 19 20 /** 21 * Loads a single class from a byte array. 22 */ 23 public class TargetLoader extends ClassLoader { 24 25 private final Map<String, byte[]> classes; 26 TargetLoader()27 public TargetLoader() { 28 super(TargetLoader.class.getClassLoader()); 29 this.classes = new HashMap<String, byte[]>(); 30 } 31 add(final String name, final byte[] bytes)32 public Class<?> add(final String name, final byte[] bytes) { 33 this.classes.put(name, bytes); 34 return load(name); 35 } 36 add(final Class<?> name, final byte[] bytes)37 public Class<?> add(final Class<?> name, final byte[] bytes) { 38 return add(name.getName(), bytes); 39 } 40 add(final Class<?> source)41 public Class<?> add(final Class<?> source) throws IOException { 42 return add(source.getName(), getClassDataAsBytes(source)); 43 } 44 load(final String sourcename)45 private Class<?> load(final String sourcename) { 46 try { 47 return loadClass(sourcename); 48 } catch (ClassNotFoundException e) { 49 // must not happen 50 throw new RuntimeException(e); 51 } 52 } 53 getClassData(Class<?> clazz)54 public static InputStream getClassData(Class<?> clazz) { 55 final String resource = "/" + clazz.getName().replace('.', '/') 56 + ".class"; 57 return clazz.getResourceAsStream(resource); 58 } 59 getClassDataAsBytes(Class<?> clazz)60 public static byte[] getClassDataAsBytes(Class<?> clazz) throws IOException { 61 InputStream in = getClassData(clazz); 62 ByteArrayOutputStream out = new ByteArrayOutputStream(); 63 byte[] buffer = new byte[0x100]; 64 int len; 65 while ((len = in.read(buffer)) != -1) { 66 out.write(buffer, 0, len); 67 } 68 in.close(); 69 return out.toByteArray(); 70 } 71 72 @Override loadClass(String name, boolean resolve)73 protected synchronized Class<?> loadClass(String name, boolean resolve) 74 throws ClassNotFoundException { 75 final byte[] bytes = classes.get(name); 76 if (bytes != null) { 77 Class<?> c = defineClass(name, bytes, 0, bytes.length); 78 if (resolve) { 79 resolveClass(c); 80 } 81 return c; 82 } 83 return super.loadClass(name, resolve); 84 } 85 86 } 87