001package io.ebean.enhance.querybean;
002
003import io.ebean.enhance.asm.ClassVisitor;
004import io.ebean.enhance.asm.Label;
005import io.ebean.enhance.asm.Opcodes;
006import io.ebean.enhance.asm.Type;
007
008import static io.ebean.enhance.common.EnhanceConstants.INIT;
009
010/**
011 * Changes the existing constructor to remove all the field initialisation as these are going to be
012 * initialised lazily by calls to our generated methods.
013 */
014public class TypeQueryConstructorAdapter extends BaseConstructorAdapter implements Opcodes, Constants {
015
016  private final ClassInfo classInfo;
017
018  private final String domainClass;
019
020  private final ClassVisitor cv;
021
022  private final String desc;
023
024  private final String signature;
025
026  /**
027  * Construct for a query bean class given its associated entity bean domain class and a class visitor.
028  */
029  public TypeQueryConstructorAdapter(ClassInfo classInfo, String domainClass, ClassVisitor cv, String desc, String signature) {
030    super();
031    this.cv = cv;
032    this.classInfo = classInfo;
033    this.domainClass = domainClass;
034    this.desc = desc;
035    this.signature = signature;
036  }
037
038  @Override
039  public void visitCode() {
040
041    boolean withDatabase = WITH_DATABASE_ARGUMENT.equals(desc);
042    boolean withEbeanServer = !withDatabase && WITH_EBEANSERVER_ARGUMENT.equals(desc);
043
044    mv = cv.visitMethod(ACC_PUBLIC, INIT, desc, signature, null);
045    mv.visitCode();
046    Label l0 = new Label();
047    mv.visitLabel(l0);
048    mv.visitLineNumber(1, l0);
049    mv.visitVarInsn(ALOAD, 0);
050    mv.visitLdcInsn(Type.getType("L" + domainClass + ";"));
051    if (withDatabase) {
052      mv.visitVarInsn(ALOAD, 1);
053      mv.visitMethodInsn(INVOKESPECIAL, TQ_ROOT_BEAN, INIT, "(Ljava/lang/Class;Lio/ebean/Database;)V", false);
054    } else if (withEbeanServer) {
055      mv.visitVarInsn(ALOAD, 1);
056      mv.visitMethodInsn(INVOKESPECIAL, TQ_ROOT_BEAN, INIT, "(Ljava/lang/Class;Lio/ebean/EbeanServer;)V", false);
057    } else {
058      mv.visitMethodInsn(INVOKESPECIAL, TQ_ROOT_BEAN, INIT, "(Ljava/lang/Class;)V", false);
059    }
060
061    Label l1 = new Label();
062    mv.visitLabel(l1);
063    mv.visitLineNumber(2, l1);
064    mv.visitVarInsn(ALOAD, 0);
065    mv.visitVarInsn(ALOAD, 0);
066    mv.visitMethodInsn(INVOKEVIRTUAL, classInfo.getClassName(), "setRoot", "(Ljava/lang/Object;)V", false);
067    Label l2 = new Label();
068    mv.visitLabel(l2);
069    mv.visitLineNumber(3, l2);
070    mv.visitInsn(RETURN);
071    Label l3 = new Label();
072    mv.visitLabel(l3);
073    mv.visitLocalVariable("this", "L" + classInfo.getClassName() + ";", null, l0, l3, 0);
074    if (withDatabase) {
075      mv.visitLocalVariable("server", "Lio/ebean/Database;", null, l0, l3, 1);
076      mv.visitMaxs(3, 2);
077    } else if (withEbeanServer) {
078      mv.visitLocalVariable("server", "Lio/ebean/EbeanServer;", null, l0, l3, 1);
079      mv.visitMaxs(3, 2);
080    } else {
081      mv.visitMaxs(2, 1);
082    }
083    mv.visitEnd();
084  }
085
086}