package org.simpleflatmapper.reflect.asm; import org.simpleflatmapper.ow2asm.ClassWriter; import org.simpleflatmapper.ow2asm.MethodVisitor; import org.simpleflatmapper.reflect.Instantiator; import static org.simpleflatmapper.ow2asm.Opcodes.ACC_BRIDGE; import static org.simpleflatmapper.ow2asm.Opcodes.ACC_FINAL; import static org.simpleflatmapper.ow2asm.Opcodes.ACC_PUBLIC; import static org.simpleflatmapper.ow2asm.Opcodes.ACC_SUPER; import static org.simpleflatmapper.ow2asm.Opcodes.ACC_SYNTHETIC; import static org.simpleflatmapper.ow2asm.Opcodes.ALOAD; import static org.simpleflatmapper.ow2asm.Opcodes.ARETURN; import static org.simpleflatmapper.ow2asm.Opcodes.CHECKCAST; import static org.simpleflatmapper.ow2asm.Opcodes.DUP; import static org.simpleflatmapper.ow2asm.Opcodes.INVOKESPECIAL; import static org.simpleflatmapper.ow2asm.Opcodes.INVOKEVIRTUAL; import static org.simpleflatmapper.ow2asm.Opcodes.NEW; import static org.simpleflatmapper.ow2asm.Opcodes.RETURN; import static org.simpleflatmapper.ow2asm.Opcodes.V1_6; public class ConstructorBuilder { public static byte[] createEmptyConstructor(final String className, final Class<?> sourceClass, final Class<?> targetClass) throws Exception { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); MethodVisitor mv; String targetType = AsmUtils.toAsmType(targetClass); String sourceType = AsmUtils.toAsmType(sourceClass); String classType = AsmUtils.toAsmType(className); String instantiatorType = AsmUtils.toAsmType(Instantiator.class); cw.visit(V1_6, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, classType, "Ljava/lang/Object;L" + instantiatorType + "<L" + targetType + ";>;", "java/lang/Object", new String[] { instantiatorType }); { mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false); mv.visitInsn(RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "newInstance", "(L" + sourceType + ";)L" + targetType + ";", null, new String[] { "java/lang/Exception" }); mv.visitCode(); mv.visitTypeInsn(NEW, targetType); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, targetType, "<init>", "()V", false); mv.visitInsn(ARETURN); mv.visitMaxs(2, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC + ACC_BRIDGE + ACC_SYNTHETIC, "newInstance", "(Ljava/lang/Object;)Ljava/lang/Object;", null, new String[] { "java/lang/Exception" }); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, sourceType); mv.visitMethodInsn(INVOKEVIRTUAL, classType, "newInstance", "(L" + sourceType + ";)L" + targetType + ";", false); mv.visitInsn(ARETURN); mv.visitMaxs(2, 2); mv.visitEnd(); } cw.visitEnd(); return AsmUtils.writeClassToFile(className, cw.toByteArray()); } }