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