1 25 26 package org.objectweb.easybeans.enhancer; 27 28 import org.objectweb.asm.ClassVisitor; 29 import org.objectweb.asm.ClassWriter; 30 import org.objectweb.asm.FieldVisitor; 31 import org.objectweb.asm.MethodVisitor; 32 import org.objectweb.asm.Opcodes; 33 import org.objectweb.asm.Type; 34 import org.objectweb.easybeans.api.Factory; 35 36 40 public abstract class CommonClassGenerator implements Opcodes { 41 42 45 public static final String ARRAY_OBJECTS = "[Ljava/lang/Object;"; 46 47 50 public static final String JAVA_LANG_OBJECT = "Ljava/lang/Object;"; 51 52 55 public static final String VOID_METHOD_JAVA_LANG_OBJECT = "(Ljava/lang/Object;)V"; 56 57 60 public static final String JAVA_LANG_EXCEPTION = "Ljava/lang/Exception;"; 61 62 65 public static final String JAVA_LANG_REFLECT_METHOD = "Ljava/lang/reflect/Method;"; 66 67 70 public static final String EASYBEANS_FACTORY = Type.getDescriptor(Factory.class); 71 72 75 public static final int GENERATED_CLASS_VERSION = V1_5; 76 77 81 private ClassWriter cw; 82 83 86 private FieldVisitor fv = null; 87 88 92 public CommonClassGenerator(final ClassWriter cw) { 93 this.cw = cw; 94 } 95 96 104 protected void addAttribute(final int access, final String name, final String desc) { 105 addAttribute(access, name, desc, null); 106 } 107 108 125 protected void addAttribute(final int access, final String name, final String desc, final Object value) { 126 fv = cw.visitField(access, name, desc, null, value); 127 fv.visitEnd(); 128 } 129 130 135 public static String encodeClassDesc(final String className) { 136 return "L" + className + ";"; 137 } 138 139 144 public static String encodeArrayClassDesc(final String className) { 145 return "[L" + className + ";"; 146 } 147 148 151 public ClassWriter getCW() { 152 return cw; 153 } 154 155 160 public static int putFieldLoadOpCode(final int sortCode) { 161 switch (sortCode) { 162 case Type.BOOLEAN: 163 case Type.BYTE: 164 case Type.CHAR: 165 case Type.SHORT: 166 case Type.INT: 167 return ILOAD; 168 case Type.FLOAT: 169 return FLOAD; 170 case Type.LONG: 171 return LLOAD; 172 case Type.DOUBLE: 173 return DLOAD; 174 default: 177 return ALOAD; 178 } 179 } 180 181 187 public static void transformPrimitiveIntoObject(final Type type, final MethodVisitor mv) { 188 switch (type.getSort()) { 189 case Type.BOOLEAN: 190 mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;"); 191 break; 192 case Type.BYTE: 193 mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;"); 194 break; 195 case Type.CHAR: 196 mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;"); 197 break; 198 case Type.SHORT: 199 mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;"); 200 break; 201 case Type.INT: 202 mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;"); 203 break; 204 case Type.FLOAT: 205 mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;"); 206 break; 207 case Type.LONG: 208 mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;"); 209 break; 210 case Type.DOUBLE: 211 mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;"); 212 break; 213 default: 216 break; 218 } 219 } 220 221 227 public static void transformObjectIntoPrimitive(final Type type, final MethodVisitor mv) { 228 switch (type.getSort()) { 229 case Type.BOOLEAN: 230 mv.visitTypeInsn(CHECKCAST, "java/lang/Boolean"); 231 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z"); 232 break; 233 case Type.BYTE: 234 mv.visitTypeInsn(CHECKCAST, "java/lang/Byte"); 235 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B"); 236 break; 237 case Type.CHAR: 238 mv.visitTypeInsn(CHECKCAST, "java/lang/Character"); 239 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C"); 240 break; 241 case Type.SHORT: 242 mv.visitTypeInsn(CHECKCAST, "java/lang/Short"); 243 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S"); 244 break; 245 case Type.INT: 246 mv.visitTypeInsn(CHECKCAST, "java/lang/Integer"); 247 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I"); 248 break; 249 case Type.FLOAT: 250 mv.visitTypeInsn(CHECKCAST, "java/lang/Float"); 251 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F"); 252 break; 253 case Type.LONG: 254 mv.visitTypeInsn(CHECKCAST, "java/lang/Long"); 255 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J"); 256 break; 257 case Type.DOUBLE: 258 mv.visitTypeInsn(CHECKCAST, "java/lang/Double"); 259 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D"); 260 break; 261 case Type.VOID: 262 mv.visitInsn(POP); 263 break; 264 case Type.ARRAY: 265 mv.visitTypeInsn(CHECKCAST, type.getDescriptor()); 266 break; 267 case Type.OBJECT: 268 mv.visitTypeInsn(CHECKCAST, type.getInternalName()); 269 break; 270 default: 271 break; 273 } 274 } 275 276 277 284 public static void addReturnType(final Type type, final MethodVisitor mv) { 285 switch (type.getSort()) { 286 case Type.BOOLEAN: 287 case Type.BYTE: 288 case Type.CHAR: 289 case Type.SHORT: 290 case Type.INT: 291 mv.visitInsn(IRETURN); 292 break; 293 case Type.FLOAT: 294 mv.visitInsn(FRETURN); 295 break; 296 case Type.LONG: 297 mv.visitInsn(LRETURN); 298 break; 299 case Type.DOUBLE: 300 mv.visitInsn(DRETURN); 301 break; 302 case Type.VOID: 303 mv.visitInsn(RETURN); 304 break; 305 case Type.ARRAY: 306 case Type.OBJECT: 307 mv.visitInsn(ARETURN); 308 break; 309 default: 310 break; 312 } 313 } 314 315 316 317 318 319 326 public static void visitClassType(final Type type, final MethodVisitor mv) { 327 switch (type.getSort()) { 328 case Type.BOOLEAN: 329 mv.visitFieldInsn(GETSTATIC, "java/lang/Boolean", "TYPE", "Ljava/lang/Class;"); 330 break; 331 case Type.BYTE: 332 mv.visitFieldInsn(GETSTATIC, "java/lang/Byte", "TYPE", "Ljava/lang/Class;"); 333 break; 334 case Type.CHAR: 335 mv.visitFieldInsn(GETSTATIC, "java/lang/Character", "TYPE", "Ljava/lang/Class;"); 336 break; 337 case Type.SHORT: 338 mv.visitFieldInsn(GETSTATIC, "java/lang/Short", "TYPE", "Ljava/lang/Class;"); 339 break; 340 case Type.INT: 341 mv.visitFieldInsn(GETSTATIC, "java/lang/Integer", "TYPE", "Ljava/lang/Class;"); 342 break; 343 case Type.FLOAT: 344 mv.visitFieldInsn(GETSTATIC, "java/lang/Float", "TYPE", "Ljava/lang/Class;"); 345 break; 346 case Type.LONG: 347 mv.visitFieldInsn(GETSTATIC, "java/lang/Long", "TYPE", "Ljava/lang/Class;"); 348 break; 349 case Type.DOUBLE: 350 mv.visitFieldInsn(GETSTATIC, "java/lang/Double", "TYPE", "Ljava/lang/Class;"); 351 break; 352 default: 355 mv.visitLdcInsn(type); 356 break; 357 } 358 } 359 360 365 public static void returnsObject(final Type returnType, final MethodVisitor mv) { 366 if (returnType.equals(Type.VOID_TYPE)) { 367 mv.visitInsn(ACONST_NULL); 368 } else { 369 transformPrimitiveIntoObject(returnType, mv); 370 } 371 mv.visitInsn(ARETURN); 372 } 373 374 381 public static void addFieldGettersSetters(final ClassVisitor cv, final String beanClassName, 382 final String fieldName, final Class clazz) { 383 String className = Type.getDescriptor(clazz); 384 addFieldGettersSetters(cv, beanClassName, fieldName, className); 385 } 386 387 394 public static void addFieldGettersSetters(final ClassVisitor cv, final String beanClassName, 395 final String fieldName, final String className) { 396 397 398 Type type = Type.getType(className); 400 401 FieldVisitor fv = cv.visitField(ACC_PRIVATE, fieldName, className, null, null); 404 fv.visitEnd(); 405 406 String appendName = fieldName.toUpperCase().charAt(0) + fieldName.substring(1); 408 String getterName = "get" + appendName; 409 410 MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, getterName, "()" + className, null, null); 415 mv.visitCode(); 416 mv.visitVarInsn(ALOAD, 0); 417 mv.visitFieldInsn(GETFIELD, beanClassName, fieldName, className); 418 addReturnType(type, mv); 420 mv.visitMaxs(0, 0); 421 mv.visitEnd(); 422 423 String setterName = "set" + appendName; 428 mv = cv.visitMethod(ACC_PUBLIC, setterName, "(" + className + ")V", null, null); 429 mv.visitCode(); 430 mv.visitVarInsn(ALOAD, 0); 431 int opCode = putFieldLoadOpCode(type.getSort()); 433 mv.visitVarInsn(opCode, 1); 434 mv.visitFieldInsn(PUTFIELD, beanClassName, fieldName, className); 435 mv.visitInsn(RETURN); 436 mv.visitMaxs(0, 0); 437 mv.visitEnd(); 438 } 439 440 446 public static void addNullGetter(final ClassVisitor cv, final String getterName, final Class clazz) { 447 String returnedClassName = Type.getDescriptor(clazz); 448 MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, getterName, "()" + returnedClassName, null, null); 453 mv.visitCode(); 454 mv.visitInsn(ACONST_NULL); 455 mv.visitInsn(ARETURN); 456 457 mv.visitMaxs(0, 0); 458 mv.visitEnd(); 459 } 460 461 462 } 463 | Popular Tags |