throw new InternalError(e.toString());
}
}
private byte[] generateProxy(Class<?> clsToProxy, String proxyName) throws ProxyGenerationException {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
FieldVisitor fv;
MethodVisitor mv;
String clsToOverride = clsToProxy.getName().replaceAll("\\.", "/");
String proxyClassName = proxyName.replaceAll("\\.", "/");
// push class signature
cw.visit(V1_5, ACC_PUBLIC + ACC_SUPER, proxyClassName, null, clsToOverride, null);
cw.visitSource(clsToOverride + ".java", null);
// push InvocationHandler fields
fv = cw.visitField(ACC_FINAL + ACC_PRIVATE, BUSSINESS_HANDLER_NAME, "Ljava/lang/reflect/InvocationHandler;", null, null);
fv.visitEnd();
fv = cw.visitField(ACC_FINAL + ACC_PRIVATE, NON_BUSINESS_HANDLER_NAME, "Ljava/lang/reflect/InvocationHandler;", null, null);
fv.visitEnd();
// push single argument constructor
mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/lang/reflect/InvocationHandler;)V", null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKESPECIAL, proxyName, "<init>", "(Ljava/lang/reflect/InvocationHandler;Ljava/lang/reflect/InvocationHandler;)V");
mv.visitInsn(RETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
// push double argument constructor
mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/lang/reflect/InvocationHandler;Ljava/lang/reflect/InvocationHandler;)V", null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, clsToOverride, "<init>", "()V");
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 1);
mv.visitFieldInsn(PUTFIELD, proxyName, BUSSINESS_HANDLER_NAME, "Ljava/lang/reflect/InvocationHandler;");
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 2);
mv.visitFieldInsn(PUTFIELD, proxyName, NON_BUSINESS_HANDLER_NAME, "Ljava/lang/reflect/InvocationHandler;");
mv.visitInsn(RETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
Map<String, List<Method>> methodMap = getNonPrivateMethods(new Class[] { clsToProxy });
for (Map.Entry<String, List<Method>> entry : methodMap.entrySet()) {
for (Method method : entry.getValue()) {
String name = method.getName();
int modifiers = method.getModifiers();
if (Modifier.isPublic(modifiers) ||
(method.getParameterTypes().length == 0 &&
("finalize".equals(name) || "clone".equals(name)))) {
// forward invocations of any public methods or
// finalize/clone methods to businessHandler
processMethod(cw, method, proxyClassName, BUSSINESS_HANDLER_NAME);
} else {
// forward invocations of any other methods to nonBusinessHandler
processMethod(cw, method, proxyClassName, NON_BUSINESS_HANDLER_NAME);
}
}
}
byte[] clsBytes = cw.toByteArray();
return clsBytes;
}