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}