001package io.ebean.enhance.entity;
002
003import io.ebean.enhance.asm.ClassVisitor;
004import io.ebean.enhance.asm.FieldVisitor;
005import io.ebean.enhance.asm.Label;
006import io.ebean.enhance.asm.MethodVisitor;
007import io.ebean.enhance.asm.Opcodes;
008import io.ebean.enhance.common.EnhanceConstants;
009
010/**
011 * Used to detect if a class has been enhanced.
012 * <p>
013 * Moved to use this over just relying on the existence of the EntityBean interface
014 * to make the enhancement more robust.
015 * </p>
016 */
017public class MarkerField implements Opcodes, EnhanceConstants {
018
019  /**
020  * The name of the static field added. Its value is the class being enhanced.
021  */
022  public static final String _EBEAN_MARKER = "_EBEAN_MARKER";
023
024  /**
025  * Add the _EBEAN_MARKER field.
026  */
027  public static String addField(ClassVisitor cv, String className) {
028
029    String cn = className.replace('/', '.');
030
031    FieldVisitor fv = cv.visitField(ACC_PRIVATE + ACC_STATIC, _EBEAN_MARKER, "Ljava/lang/String;", null, cn);
032    fv.visitEnd();
033
034    return cn;
035  }
036
037  /**
038  * Generate the _ebean_getMarker() method.
039  *
040  * <pre>
041  * public String _ebean_getMarker() {
042  *     return _EBEAN_MARKER;
043  * }
044  * </pre>
045  */
046  public static void addGetMarker(ClassVisitor cv, String className) {
047
048
049    MethodVisitor mv;
050
051    mv = cv.visitMethod(ACC_PUBLIC, "_ebean_getMarker", "()Ljava/lang/String;", null, null);
052    mv.visitCode();
053    Label l0 = new Label();
054    mv.visitLabel(l0);
055    mv.visitLineNumber(1, l0);
056    mv.visitFieldInsn(GETSTATIC, className, "_EBEAN_MARKER", "Ljava/lang/String;");
057    mv.visitInsn(ARETURN);
058    Label l1 = new Label();
059    mv.visitLabel(l1);
060    mv.visitLocalVariable("this", "L"+className+";", null, l0, l1, 0);
061    mv.visitMaxs(1, 1);
062    mv.visitEnd();
063  }
064}