// ex: se sts=4 sw=4 expandtab:
/*
* Yeti language compiler java bytecode generator.
*
* Copyright (c) 2007-2013 Madis Janson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package yeti.lang.compiler;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import yeti.lang.Fun2;
import java.util.HashMap;
class Loader extends Fun2 {
MemLoader mem;
Loader(ClassLoader cl) {
mem = new MemLoader(cl);
}
public Object apply(Object className, Object codeBytes) {
String name = (String) className;
// to a dotted classname used by loadClass
mem.classes.put(name.substring(0, name.length() - 6).replace('/', '.'),
codeBytes);
return null;
}
}
class MemLoader extends ClassLoader {
HashMap classes = new HashMap();
MemLoader(ClassLoader cl) {
super(cl != null ? cl : Thread.currentThread().getContextClassLoader());
}
// override loadClass to ensure loading our own class
// even when it already exists in current classpath
protected synchronized Class loadClass(String name, boolean resolve)
throws ClassNotFoundException {
Class loaded = findLoadedClass(name);
if (loaded == null) {
byte[] code = (byte[]) classes.get(name);
if (code == null) {
return super.loadClass(name, resolve);
}
loaded = defineClass(name, code, 0, code.length);
}
if (resolve) {
resolveClass(loaded);
}
return loaded;
}
public InputStream getResourceAsStream(String path) {
if (path.endsWith(".class")) {
String name =
path.substring(0, path.length() - 6).replace('.', '/');
byte[] code = (byte[]) classes.get(name);
if (code != null)
return new ByteArrayInputStream(code);
}
return super.getResourceAsStream(path);
}
}