1 18 package org.objectweb.speedo.generation.enhancer; 19 20 import org.objectweb.asm.ClassVisitor; 21 import org.objectweb.asm.CodeVisitor; 22 import org.objectweb.asm.Constants; 23 import org.objectweb.asm.Type; 24 import org.objectweb.asm.Attribute; 25 import org.objectweb.speedo.metadata.SpeedoClass; 26 import org.objectweb.speedo.metadata.SpeedoField; 27 import org.objectweb.speedo.generation.lib.NamingRules; 28 import org.objectweb.speedo.naming.api.UserId; 29 import org.objectweb.util.monolog.api.Logger; 30 import org.objectweb.util.monolog.api.BasicLevel; 31 32 import java.util.Iterator ; 33 34 40 public class UserIdEnhancer extends LoggedClassAdapter { 41 42 protected SpeedoClass jdoClass; 43 44 public final static String ADDED_FIELD_NAME = "jdoPersistentClassName"; 45 public final static String ADDED_FIELD_DESC = "Ljava/lang/String;"; 46 47 private String className ; 48 49 public UserIdEnhancer(ClassVisitor classVisitor, 50 SpeedoClass jdoClass, 51 Logger logger) { 52 super(classVisitor, logger); 53 this.jdoClass = jdoClass; 54 } 55 56 public void visit(final int version, final int access, 57 final String cn, 58 final String superName, 59 final String [] interfaces, 60 final String sourceFile) { 61 className = cn; 62 String [] itfs; 63 String pngcn = NamingRules.pngName(jdoClass.objectidClass).replace('.', '/'); 64 boolean alreadyPNG = false; 65 String sncn = UserId.class.getName().replace('.','/'); 66 if (interfaces == null || interfaces.length==0) { 67 itfs = new String []{pngcn, sncn}; 68 } else { 69 int i=0; 70 while(i<interfaces.length && !interfaces[i].equals(pngcn)) { 71 i++; 72 } 73 alreadyPNG = i<interfaces.length; 74 if (alreadyPNG) { 75 itfs = interfaces; 76 } else { 77 itfs = new String [interfaces.length + 2]; 78 System.arraycopy(interfaces, 0, itfs, 2, interfaces.length); 79 itfs[0] = pngcn; 80 itfs[1] = UserId.class.getName().replace('.','/'); 81 } 82 } 83 if (alreadyPNG) { 84 logger.log(BasicLevel.DEBUG, "The class " + className 85 + " already contains the interface " + pngcn + " and " + sncn); 86 super.visit(version, access, className, superName, interfaces, sourceFile); 87 return; 88 } 89 logger.log(BasicLevel.DEBUG, "Add to the class " + className 90 + " the interface " + pngcn); 91 logger.log(BasicLevel.DEBUG, "Add to the class " + className 92 + " the interface " + sncn); 93 super.visit(version, access, className, superName, itfs, sourceFile); 94 95 SpeedoClass pkFieldClassHolder = jdoClass; 96 if (jdoClass.superClassName != null) { 97 pkFieldClassHolder = jdoClass.getAncestor(); 98 } 99 100 for(Iterator it = pkFieldClassHolder.jdoField.values().iterator(); it.hasNext();) { 101 SpeedoField sp = (SpeedoField) it.next(); 102 if (sp.primaryKey) { 103 String methodName = "pnGet" + upperFL(sp.name); 104 logger.log(BasicLevel.DEBUG, "Add to the class " + className 105 + " the method " + methodName); 106 CodeVisitor _cv = this.cv.visitMethod( 107 Constants.ACC_PUBLIC, 108 methodName, 109 "(Ljava/lang/Object;)" + sp.desc, 110 null, 111 null); 112 _cv.visitVarInsn(Constants.ALOAD, 0); 113 _cv.visitFieldInsn(Constants.GETFIELD, className, sp.name, sp.desc); 114 Type returnType = Type.getType(sp.desc); 115 _cv.visitInsn(returnType.getOpcode(Constants.IRETURN)); 116 _cv.visitMaxs( 117 (sp.desc.equals("J") || sp.desc.equals("D")) ? 2 : 1, 118 2); 119 } 120 } 121 logger.log(BasicLevel.DEBUG, "Add to the class " + className 124 + " the field " + ADDED_FIELD_NAME); 125 cv.visitField(Constants.ACC_PRIVATE, ADDED_FIELD_NAME, 126 ADDED_FIELD_DESC, null, null); 127 128 String methodName = "jdoGetPersistentClassName"; 130 logger.log(BasicLevel.DEBUG, "Add to the class " + className 131 + " the method " + methodName); 132 CodeVisitor _cv = this.cv.visitMethod( 133 Constants.ACC_PUBLIC, 134 methodName, 135 "()Ljava/lang/String;", 136 null, 137 null); 138 _cv.visitVarInsn(Constants.ALOAD, 0); 139 _cv.visitFieldInsn(Constants.GETFIELD, 140 className, ADDED_FIELD_NAME, ADDED_FIELD_DESC); 141 Type returnType = Type.getType(ADDED_FIELD_DESC); 142 _cv.visitInsn(returnType.getOpcode(Constants.IRETURN)); 143 _cv.visitMaxs(1, 2); 144 145 methodName = "jdoSetPersistentClassName"; 147 logger.log(BasicLevel.DEBUG, "Add to the class " + className 148 + " the method " + methodName); 149 _cv = this.cv.visitMethod( 150 Constants.ACC_PUBLIC, 151 methodName, 152 "(Ljava/lang/String;)V", 153 null, 154 null); 155 _cv.visitVarInsn(Constants.ALOAD, 0); 156 _cv.visitVarInsn(Constants.ALOAD, 1); 157 _cv.visitFieldInsn(Constants.PUTFIELD, 158 className, ADDED_FIELD_NAME, ADDED_FIELD_DESC); 159 _cv.visitInsn(Constants.RETURN); 160 _cv.visitMaxs(2, 2); 161 } 162 163 public CodeVisitor visitMethod(final int access, 164 final String name, 165 final String desc, 166 final String [] exceptions, 167 final Attribute attrs) { 168 CodeVisitor c = cv.visitMethod(access, name, desc, exceptions, attrs); 169 if (name.equals("<init>")) { 170 c.visitVarInsn(Constants.ALOAD, 0); 171 c.visitLdcInsn(jdoClass.getFQName()); c.visitFieldInsn(Constants.PUTFIELD, className, 173 ADDED_FIELD_NAME, ADDED_FIELD_DESC); 174 } 175 return c; 176 } 177 178 private String upperFL(String str) { 179 if (str == null || str.length()==0) { 180 return str; 181 } else if (str.length() == 1) { 182 return String.valueOf(Character.toUpperCase(str.charAt(0))); 183 } else { 184 return Character.toUpperCase(str.charAt(0)) + str.substring(1); 185 } 186 } 187 } 188 | Popular Tags |