String cleanName = thisClassName.replace('/', '.');
boolean isPackagePrivate = false;
DynamicClassLoader loader;
if (! Modifier.isPublic(cl.getModifiers())
&& ! Modifier.isProtected(cl.getModifiers())) {
isPackagePrivate = true;
}
if (isPackagePrivate)
loader = (DynamicClassLoader) cl.getClassLoader();
else
loader = (DynamicClassLoader) Thread.currentThread().getContextClassLoader();
try {
_proxyClass = Class.forName(cleanName, false, loader);
} catch (ClassNotFoundException e) {
log.log(Level.FINEST, e.toString(), e);
}
if (_proxyClass == null) {
JavaClassLoader jLoader = new JavaClassLoader(cl.getClassLoader());
JavaClass jClass = new JavaClass(jLoader);
jClass.setAccessFlags(Modifier.PUBLIC);
jClass.setWrite(true);
jClass.setMajor(49);
jClass.setMinor(0);
String superClassName;
if (! cl.isInterface())
superClassName = typeClassName;
else
superClassName = "java/lang/Object";
jClass.setSuperClass(superClassName);
jClass.setThisClass(thisClassName);
for (Class<?> iface : types) {
if (iface.isInterface())
jClass.addInterface(iface.getName().replace('.', '/'));
}
jClass.addInterface(ScopeProxy.class.getName().replace('.', '/'));
JavaField factoryField =
jClass.createField("_factory",
"Lcom/caucho/config/inject/InjectManager$ReferenceFactory;");
factoryField.setAccessFlags(Modifier.PRIVATE);
JavaMethod ctor =
jClass.createMethod("<init>",
"(Lcom/caucho/config/inject/InjectManager$ReferenceFactory;)V");
ctor.setAccessFlags(Modifier.PUBLIC);
CodeWriterAttribute code = ctor.createCodeWriter();
code.setMaxLocals(3);
code.setMaxStack(4);
code.pushObjectVar(0);
code.pushObjectVar(1);
code.putField(thisClassName, factoryField.getName(),
factoryField.getDescriptor());
code.pushObjectVar(0);
code.invokespecial(superClassName, "<init>", "()V", 1, 0);
code.addReturn();
code.close();
createGetDelegateMethod(jClass);
createSerialize(jClass);
for (Method method : getMethods(_types)) {
if (Modifier.isStatic(method.getModifiers()))
continue;
if (Modifier.isFinal(method.getModifiers()))
continue;
if (isRemoveMethod(_beanClass, method))
createRemoveProxyMethod(jClass, method, method.getDeclaringClass().isInterface());
else
createProxyMethod(jClass, method, method.getDeclaringClass().isInterface());
}
ByteArrayOutputStream bos = new ByteArrayOutputStream();
WriteStream out = Vfs.openWrite(bos);
jClass.write(out);
out.close();
byte[] buffer = bos.toByteArray();
/*
* try { out = Vfs.lookup("file:/tmp/caucho/qa/temp.class").openWrite();
* out.write(buffer, 0, buffer.length); out.close(); } catch
* (IOException e) { }
*/
if (isPackagePrivate) {
// ioc/0517
_proxyClass = loader.loadClass(cleanName, buffer);
}
else {
ProxyClassLoader proxyLoader = new ProxyClassLoader(loader);
_proxyClass = proxyLoader.loadClass(cleanName, buffer);