private static byte[] generateBytes(final Class<?> classToProxy) throws ProxyGenerationException {
final Map<String, MethodVisitor> visitors = new HashMap<String, MethodVisitor>();
final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
final String proxyClassFileName = getSubclassName(classToProxy).replace('.', '/');
final String classFileName = classToProxy.getName().replace('.', '/');
cw.visit(V1_5, ACC_PUBLIC + ACC_SUPER, proxyClassFileName, null, classFileName, null);
cw.visitSource(classFileName + ".java", null);
// push InvocationHandler field
cw.visitField(ACC_FINAL + ACC_PRIVATE, "this$handler", "Ljava/lang/reflect/InvocationHandler;", null, null).visitEnd();
for (final Constructor<?> constructor : classToProxy.getConstructors()) {
if (!Modifier.isPublic(constructor.getModifiers())) {
continue;
}
final MethodVisitor mv = visitConstructor(cw, proxyClassFileName, classFileName, constructor);
visitors.put("<init>" + Type.getConstructorDescriptor(constructor), mv);
}
final Map<String, List<Method>> methodMap = new HashMap<String, List<Method>>();
getNonPrivateMethods(classToProxy, methodMap);
// Iterate over the public methods
for (final Map.Entry<String, List<Method>> entry : methodMap.entrySet()) {
for (final Method method : entry.getValue()) {
if (Modifier.isAbstract(method.getModifiers())) {
final MethodVisitor visitor = LocalBeanProxyFactory.visit(cw, method, proxyClassFileName, "this$handler");
visitors.put(method.getName() + Type.getMethodDescriptor(method), visitor);
}
}
}
copyClassAnnotations(classToProxy, cw);
copyMethodAnnotations(classToProxy, visitors);
// This should never be reached, but just in case
for (final MethodVisitor visitor : visitors.values()) {
visitor.visitEnd();
}
return cw.toByteArray();
}