1 18 package org.objectweb.speedo.generation.enhancer; 19 20 import org.objectweb.asm.Attribute; 21 import org.objectweb.asm.ClassVisitor; 22 import org.objectweb.asm.CodeVisitor; 23 import org.objectweb.asm.Constants; 24 import org.objectweb.asm.Label; 25 import org.objectweb.speedo.generation.lib.NamingRules; 26 import org.objectweb.speedo.metadata.SpeedoClass; 27 import org.objectweb.speedo.tools.StringReplace; 28 import org.objectweb.util.monolog.api.BasicLevel; 29 import org.objectweb.util.monolog.api.Logger; 30 31 40 public class JDOImplRegistrationAdder extends LoggedClassAdapter { 41 42 45 String className; 46 47 String homeClassName; 48 49 50 53 boolean clinitfound = false; 54 55 59 boolean classFieldfound = false; 60 61 64 boolean classMethodfound = false; 65 66 70 private String fieldName; 71 72 private SpeedoClass sc; 73 74 public JDOImplRegistrationAdder(ClassVisitor classVisitor) { 75 super(classVisitor); 76 } 77 78 public JDOImplRegistrationAdder(ClassVisitor classVisitor, SpeedoClass sc, Logger logger) { 79 super(classVisitor, logger); 80 this.sc = sc; 81 } 82 83 public void visit(final int version, final int access, 84 final String name, 85 final String superName, 86 final String [] interfaces, 87 final String sourceFile) { 88 className = name; 89 homeClassName = NamingRules.homeName(name); 90 fieldName = "class$" + className.replace('/', '$'); 91 super.visit(version, access, name, superName, interfaces, sourceFile); 92 logger.log(BasicLevel.DEBUG, "Class name: " + className); 93 } 94 95 public void visitField(int i, String s, String s1, Object o, Attribute attribute) { 96 super.visitField(i, s, s1, o, attribute); 97 classFieldfound |= s.equals(fieldName); 98 } 99 100 public CodeVisitor visitMethod(final int access, 101 final String name, 102 final String desc, 103 final String [] exceptions, 104 final Attribute attrs) { 105 CodeVisitor c = cv.visitMethod(access, name, desc, exceptions, attrs); 106 if (name.equals("<clinit>")) { 107 clinitfound = true; 108 addClassRegistrationCode(c); 109 } else if (name.equals("class$")) { 110 classMethodfound = true; 111 } 112 return c; 113 } 114 115 public void visitEnd() { 116 if (!clinitfound) { 117 logger.log(BasicLevel.DEBUG, "Adding static area in " + className); 118 CodeVisitor c = cv.visitMethod(Constants.ACC_STATIC, 119 "<clinit>", "()V", null, null); 120 addClassRegistrationCode(c); 121 c.visitInsn(RETURN); 122 c.visitMaxs(0, 0); 123 } 124 125 if (!classMethodfound) { 126 logger.log(BasicLevel.DEBUG, "Adding static method class$(String)Class in " + className); 127 CodeVisitor c = cv.visitMethod(ACC_STATIC + ACC_SYNTHETIC, "class$", 128 "(Ljava/lang/String;)Ljava/lang/Class;", null, null); 129 Label l0 = new Label(); 130 c.visitLabel(l0); 131 c.visitVarInsn(ALOAD, 0); 132 c.visitMethodInsn(INVOKESTATIC, "java/lang/Class", "forName", 133 "(Ljava/lang/String;)Ljava/lang/Class;"); 134 Label l1 = new Label(); 135 c.visitLabel(l1); 136 c.visitInsn(ARETURN); 137 Label l2 = new Label(); 138 c.visitLabel(l2); 139 c.visitVarInsn(ASTORE, 1); 140 c.visitTypeInsn(NEW, "java/lang/NoClassDefFoundError"); 141 c.visitInsn(DUP); 142 c.visitVarInsn(ALOAD, 1); 143 c.visitMethodInsn(INVOKEVIRTUAL, "java/lang/ClassNotFoundException", 144 "getMessage", "()Ljava/lang/String;"); 145 c.visitMethodInsn(INVOKESPECIAL, "java/lang/NoClassDefFoundError", 146 "<init>", "(Ljava/lang/String;)V"); 147 c.visitInsn(ATHROW); 148 c.visitTryCatchBlock(l0, l1, l2, "java/lang/ClassNotFoundException"); 149 c.visitMaxs(3, 2); 150 } 151 if (!classFieldfound) { 152 logger.log(BasicLevel.DEBUG, "Adding static field class$ in " + className); 153 cv.visitField(ACC_STATIC + ACC_SYNTHETIC, fieldName, 154 "Ljava/lang/Class;", null, null); 155 } 156 157 super.visitEnd(); 158 } 159 160 164 private void addClassRegistrationCode(CodeVisitor c) { 165 c.visitFieldInsn(Constants.GETSTATIC, 167 className, 168 fieldName, 169 "Ljava/lang/Class;"); 170 171 Label l1 = new Label(); 172 c.visitJumpInsn(Constants.IFNONNULL, l1); 173 c.visitLdcInsn(StringReplace.replaceChar('/', '.', className)); 174 c.visitMethodInsn(Constants.INVOKESTATIC, className, "class$", 175 "(Ljava/lang/String;)Ljava/lang/Class;"); 176 c.visitInsn(Constants.DUP); 177 c.visitFieldInsn(Constants.PUTSTATIC, 178 className, 179 fieldName, 180 "Ljava/lang/Class;"); 181 Label l2 = new Label(); 182 c.visitJumpInsn(Constants.GOTO, l2); 183 c.visitLabel(l1); 184 c.visitFieldInsn(Constants.GETSTATIC, 185 className, 186 fieldName, 187 "Ljava/lang/Class;"); 188 c.visitLabel(l2); 189 c.visitFieldInsn(GETSTATIC, homeClassName, "FIELD_NAMES", "[Ljava/lang/String;"); 191 c.visitFieldInsn(GETSTATIC, homeClassName, "FIELD_TYPES", "[Ljava/lang/Class;"); 193 c.visitFieldInsn(GETSTATIC, homeClassName, "FIELD_FLAGS", "[B"); 195 c.visitFieldInsn(GETSTATIC, homeClassName, "SUPER_CLASS", "Ljava/lang/Class;"); 197 c.visitInsn(ACONST_NULL); 199 c.visitMethodInsn(Constants.INVOKESTATIC, 200 "javax/jdo/spi/JDOImplHelper", 201 "registerClass", 202 "(Ljava/lang/Class;[Ljava/lang/String;[Ljava/lang/Class;[BLjava/lang/Class;Ljavax/jdo/spi/PersistenceCapable;)V"); 203 } 204 } 205 | Popular Tags |