
org.sfm.reflect.asm.JdbcMapperAsmBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of simpleFlatMapper Show documentation
Show all versions of simpleFlatMapper Show documentation
Java library to map flat record - ResultSet, csv - to java object with minimum configuration and low footprint.
package org.sfm.reflect.asm;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.sfm.jdbc.impl.AbstractJdbcMapperImpl;
import org.sfm.map.RowHandlerErrorHandler;
import org.sfm.map.impl.FieldMapper;
import org.sfm.reflect.Instantiator;
import java.sql.ResultSet;
import static org.objectweb.asm.Opcodes.*;
public class JdbcMapperAsmBuilder {
private static final String ABSTRACT_JDBC_MAPPER_IMPL_TYPE = AsmUtils.toType(AbstractJdbcMapperImpl.class);
private static final String FIELD_MAPPER_TYPE = AsmUtils.toType(FieldMapper.class);
private static final String INSTANTIATOR_TYPE = AsmUtils.toType(Instantiator.class);
private static final String ROW_HANDLER_ERROR_HANDLER_TYPE = AsmUtils.toType(RowHandlerErrorHandler.class);
public static byte[] dump (final String className, final FieldMapper[] mappers, final Class target) throws Exception {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
MethodVisitor mv;
Class sourceClass = ResultSet.class;
final String targetType = AsmUtils.toType(target);
final String sourceType = AsmUtils.toType(sourceClass);
final String classType = AsmUtils.toType(className);
cw.visit(V1_6, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, classType, "L" + ABSTRACT_JDBC_MAPPER_IMPL_TYPE + ";", ABSTRACT_JDBC_MAPPER_IMPL_TYPE, null);
for(int i = 0; i < mappers.length; i++) {
declareMapperFields(cw, mappers[i], i);
}
{
mv = cw.visitMethod(ACC_PUBLIC, "", "([L" + FIELD_MAPPER_TYPE + ";L" + INSTANTIATOR_TYPE + ";L" + ROW_HANDLER_ERROR_HANDLER_TYPE + ";)V", "([L" + FIELD_MAPPER_TYPE +";L" + AsmUtils.toType(Instantiator.class) + ";L" + AsmUtils.toType(RowHandlerErrorHandler.class) + ";)V", null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 2);
mv.visitVarInsn(ALOAD, 3);
mv.visitMethodInsn(INVOKESPECIAL, ABSTRACT_JDBC_MAPPER_IMPL_TYPE, "", "(L" + INSTANTIATOR_TYPE + ";L" + ROW_HANDLER_ERROR_HANDLER_TYPE + ";)V", false);
for(int i = 0; i < mappers.length; i++) {
addGetterSetterInit(mv, mappers[i], i, classType);
}
mv.visitInsn(RETURN);
mv.visitMaxs(3, 3);
mv.visitEnd();
}
{
mv = cw.visitMethod(ACC_PROTECTED + ACC_FINAL, "mapFields", "(L" + sourceType + ";L" + targetType + ";)V", null, new String[] { "java/lang/Exception" });
mv.visitCode();
for(int i = 0; i < mappers.length; i++) {
generateMappingCall(mv, mappers[i], i, classType, sourceType, targetType);
}
mv.visitInsn(RETURN);
mv.visitMaxs(3, 3);
}
{
mv = cw.visitMethod(ACC_PROTECTED + ACC_BRIDGE + ACC_SYNTHETIC, "mapFields", "(Ljava/lang/Object;Ljava/lang/Object;)V", null, new String[] { "java/lang/Exception" });
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 1);
mv.visitTypeInsn(CHECKCAST, sourceType);
mv.visitVarInsn(ALOAD, 2);
mv.visitTypeInsn(CHECKCAST, targetType);
mv.visitMethodInsn(INVOKEVIRTUAL, classType, "mapFields", "(L" + sourceType + ";L" + targetType + ";)V", false);
mv.visitInsn(RETURN);
mv.visitMaxs(3, 3);
mv.visitEnd();
}
cw.visitEnd();
return AsmUtils.writeClassToFile(className, cw.toByteArray());
}
private static void generateMappingCall(MethodVisitor mv,
FieldMapper mapper, int index, String classType, String sourceType, String targetType) {
if (mapper ==null) return;
Class> mapperClass = AsmUtils.getPublicOrInterfaceClass(mapper.getClass());
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, classType, "mapper" + index, "L" + AsmUtils.toType(mapperClass) + ";");
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(ALOAD, 2);
if (AsmUtils.isStillGeneric(mapperClass)) {
AsmUtils.invoke(mv, mapperClass, "map", "(Ljava/lang/Object;Ljava/lang/Object;)V");
} else {
AsmUtils.invoke(mv, mapperClass, "map", "(L" + sourceType + ";L" + targetType +";)V");
}
}
private static void addGetterSetterInit(MethodVisitor mv,
FieldMapper mapper, int index, String classType) {
if (mapper == null) return;
Class> mapperClass = mapper.getClass();
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 1);
addIndex(mv, index);
mv.visitInsn(AALOAD);
mv.visitTypeInsn(CHECKCAST, AsmUtils.toType(mapperClass));
mv.visitFieldInsn(PUTFIELD, classType, "mapper" + index, "L" + AsmUtils.toType(mapperClass) +";");
}
private static void declareMapperFields(ClassWriter cw,
FieldMapper mapper, int index) {
if (mapper == null)
return;
FieldVisitor fv;
Class> mapperClass = AsmUtils.getPublicOrInterfaceClass(mapper.getClass());
fv = cw.visitField(ACC_PRIVATE + ACC_FINAL, "mapper" + index, "L" + AsmUtils.toType(mapperClass) + ";", "L" + AsmUtils.toTypeWithParam(mapperClass) + ";", null);
fv.visitEnd();
}
private static void addIndex(MethodVisitor mv, int i) {
switch(i) {
case 0:
mv.visitInsn(ICONST_0);
return;
case 1:
mv.visitInsn(ICONST_1);
return;
case 2:
mv.visitInsn(ICONST_2);
return;
case 3:
mv.visitInsn(ICONST_3);
return;
case 4:
mv.visitInsn(ICONST_4);
return;
case 5:
mv.visitInsn(ICONST_5);
return;
default:
mv.visitIntInsn(BIPUSH, i);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy