137dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta/* 237dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta * Copyright (C) 2015 The Android Open Source Project 337dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta * 437dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta * Licensed under the Apache License, Version 2.0 (the "License"); 537dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta * you may not use this file except in compliance with the License. 637dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta * You may obtain a copy of the License at 737dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta * 837dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta * http://www.apache.org/licenses/LICENSE-2.0 937dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta * 1037dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta * Unless required by applicable law or agreed to in writing, software 1137dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta * distributed under the License is distributed on an "AS IS" BASIS, 1237dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1337dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta * See the License for the specific language governing permissions and 1437dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta * limitations under the License. 1537dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta */ 1637dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta 1737dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Guptapackage com.android.layoutlib.bridge.intensive.setup; 1837dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta 1937dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Guptaimport java.io.ByteArrayOutputStream; 2037dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Guptaimport java.io.IOException; 2137dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Guptaimport java.io.InputStream; 2237dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Guptaimport java.util.Map; 2337dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta 2437dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Guptaimport com.google.android.collect.Maps; 2537dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta 2637dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta/** 2737dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta * The ClassLoader to load the project's classes. 2837dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta */ 2937dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Guptapublic class ModuleClassLoader extends ClassLoader { 3037dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta 3137dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta private final Map<String, Class<?>> mClasses = Maps.newHashMap(); 3237dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta private final String mClassLocation; 3337dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta 3437dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta public ModuleClassLoader(String classLocation) { 3537dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta mClassLocation = classLocation; 3637dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta } 3737dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta 3837dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta @Override 3937dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta protected Class<?> findClass(String name) throws ClassNotFoundException { 4037dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta Class<?> aClass = mClasses.get(name); 4137dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta if (aClass != null) { 4237dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta return aClass; 4337dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta } 4437dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta String pathName = mClassLocation.concat(name.replace('.', '/')).concat(".class"); 4537dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta InputStream classInputStream = getClass().getResourceAsStream(pathName); 4637dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta if (classInputStream == null) { 4737dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta throw new ClassNotFoundException("Unable to find class " + name + " at " + pathName); 4837dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta } 4937dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta byte[] data; 5037dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta try { 5137dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta ByteArrayOutputStream buffer = new ByteArrayOutputStream(); 5237dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta int nRead; 5337dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta data = new byte[16384]; // 16k 5437dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta while ((nRead = classInputStream.read(data, 0, data.length)) != -1) { 5537dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta buffer.write(data, 0, nRead); 5637dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta } 5737dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta buffer.flush(); 5837dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta data = buffer.toByteArray(); 5937dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta } catch (IOException e) { 6037dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta // Wrap the exception with ClassNotFoundException so that caller can deal with it. 6137dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta throw new ClassNotFoundException("Unable to load class " + name, e); 6237dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta } 6337dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta aClass = defineClass(name, data, 0, data.length); 6437dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta mClasses.put(name, aClass); 6537dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta return aClass; 6637dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta } 6737dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta} 68