1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.layoutlib.bridge.intensive.util; 18 19import java.io.IOException; 20import java.util.HashMap; 21import java.util.Map; 22 23import libcore.io.Streams; 24 25/** 26 * Module class loader that loads classes from the test project. 27 */ 28public class ModuleClassLoader extends ClassLoader { 29 private final Map<String, Class<?>> mClasses = new HashMap<>(); 30 private String myModuleRoot; 31 32 /** 33 * @param moduleRoot The path to the module root 34 * @param parent The parent class loader 35 */ 36 public ModuleClassLoader(String moduleRoot, ClassLoader parent) { 37 super(parent); 38 myModuleRoot = moduleRoot + (moduleRoot.endsWith("/") ? "" : "/"); 39 } 40 41 @Override 42 protected Class<?> findClass(String name) throws ClassNotFoundException { 43 try { 44 return super.findClass(name); 45 } catch (ClassNotFoundException ignored) { 46 } 47 48 Class<?> clazz = mClasses.get(name); 49 if (clazz == null) { 50 String path = name.replace('.', '/').concat(".class"); 51 try { 52 byte[] b = Streams.readFully(getResourceAsStream(myModuleRoot + path)); 53 clazz = defineClass(name, b, 0, b.length); 54 mClasses.put(name, clazz); 55 } catch (IOException ignore) { 56 throw new ClassNotFoundException(name + " not found"); 57 } 58 } 59 60 return clazz; 61 } 62} 63