All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.ebean.enhance.entity.MethodFieldAdapter Maven / Gradle / Ivy

package io.ebean.enhance.entity;

import io.ebean.enhance.asm.AnnotationVisitor;
import io.ebean.enhance.asm.Label;
import io.ebean.enhance.asm.MethodVisitor;
import io.ebean.enhance.asm.Opcodes;
import io.ebean.enhance.common.ClassMeta;
import io.ebean.enhance.common.EnhanceConstants;

import static io.ebean.enhance.Transformer.EBEAN_ASM_VERSION;

/**
 * Changes the method code from using PUTFIELD and GETFIELD to calling our
 * special field interception methods.
 * 

* This should only be performed on non-transient methods. If a method has the * Transient annotation then it is not transformed in this way. *

*/ final class MethodFieldAdapter extends MethodVisitor implements Opcodes, EnhanceConstants { private final ClassMeta meta; private final String className; private final String methodDescription; private boolean transientAnnotation; MethodFieldAdapter(MethodVisitor mv, ClassMeta meta, String methodDescription) { super(EBEAN_ASM_VERSION, mv); this.meta = meta; this.className = meta.className(); this.methodDescription = methodDescription; } /** * Checks for the Transient annotation. *

* If this annotation is on the method then field interception is not * applied (Aka the method is not transformed). */ @Override public AnnotationVisitor visitAnnotation(String desc, boolean visible) { if (desc.equals(Javax.Transient) || desc.equals(Jakarta.Transient)) { transientAnnotation = true; } return super.visitAnnotation(desc, visible); } @Override public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) { super.visitLocalVariable(name, desc, signature, start, end, index); } @Override public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { super.visitMethodInsn(opcode, owner, name, desc, itf); } @Override public void visitFieldInsn(int opcode, String owner, String name, String desc) { if (transientAnnotation) { // The whole method is left as is super.visitFieldInsn(opcode, owner, name, desc); return; } if (opcode == Opcodes.GETSTATIC || opcode == Opcodes.PUTSTATIC) { super.visitFieldInsn(opcode, owner, name, desc); return; } if (isNonPersistentField(owner, name)) { if (meta.isLog(4)) { meta.log(" ... info: non-persistent field " + owner + " " + name + " in " + methodDescription); } super.visitFieldInsn(opcode, owner, name, desc); return; } // every basicField has a special set of field interception methods if (opcode == Opcodes.GETFIELD) { String methodName = "_ebean_get_" + name; String methodDesc = "()" + desc; if (meta.isLog(4)) { meta.log("GETFIELD method:" + methodDescription + " field:" + name + " > " + methodName + " " + methodDesc); } super.visitMethodInsn(INVOKEVIRTUAL, className, methodName, methodDesc, false); } else if (opcode == Opcodes.PUTFIELD) { String methodName = "_ebean_set_" + name; String methodDesc = "(" + desc + ")V"; if (meta.isLog(4)) { meta.log("PUTFIELD method:" + methodDescription + " field:" + name + " > " + methodName + " " + methodDesc); } super.visitMethodInsn(INVOKEVIRTUAL, className, methodName, methodDesc, false); } else { meta.log("Warning adapting method:" + methodDescription + "; unexpected static access to a persistent field?? " + name + " opCode not GETFIELD or PUTFIELD?? opCode:" + opcode + ""); super.visitFieldInsn(opcode, owner, name, desc); } } /** * Return true if the field is non-persistent and hence should not be intercepted. */ private boolean isNonPersistentField(String owner, String name) { return !isSameOwner(owner) || !meta.isFieldPersistent(name); } /** * Return true if the owner type is the same as this class being enhanced. */ private boolean isSameOwner(String owner) { return className.equals(owner); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy