1 25 26 package org.objectweb.easybeans.enhancer.injection; 27 28 import static org.objectweb.easybeans.injection.JNDILookupHelper.JndiType.JAVA_COMP; 29 import static org.objectweb.easybeans.injection.JNDILookupHelper.JndiType.JAVA_COMP_ENV; 30 import static org.objectweb.easybeans.injection.JNDILookupHelper.JndiType.REGISTRY; 31 32 import java.util.Arrays ; 33 import java.util.List ; 34 import java.util.Map ; 35 36 import javax.ejb.MessageDrivenContext ; 37 import javax.ejb.SessionContext ; 38 import javax.ejb.TimerService ; 39 import javax.jms.Queue ; 40 import javax.jms.QueueConnectionFactory ; 41 import javax.jms.Topic ; 42 import javax.jms.TopicConnectionFactory ; 43 import javax.persistence.EntityManager; 44 import javax.persistence.EntityManagerFactory; 45 import javax.sql.DataSource ; 46 import javax.transaction.UserTransaction ; 47 48 import org.objectweb.asm.ClassAdapter; 49 import org.objectweb.asm.ClassVisitor; 50 import org.objectweb.asm.MethodVisitor; 51 import org.objectweb.asm.Opcodes; 52 import org.objectweb.asm.Type; 53 import org.objectweb.easybeans.api.Factory; 54 import org.objectweb.easybeans.api.container.EZBEJBContext; 55 import org.objectweb.easybeans.api.container.EZBMDBContext; 56 import org.objectweb.easybeans.api.container.EZBSessionContext; 57 import org.objectweb.easybeans.deployment.annotations.JMethod; 58 import org.objectweb.easybeans.deployment.annotations.impl.JAnnotationResource; 59 import org.objectweb.easybeans.deployment.annotations.impl.JEjbEJB; 60 import org.objectweb.easybeans.deployment.annotations.impl.JavaxPersistenceContext; 61 import org.objectweb.easybeans.deployment.annotations.impl.JavaxPersistenceUnit; 62 import org.objectweb.easybeans.deployment.annotations.metadata.ClassAnnotationMetadata; 63 import org.objectweb.easybeans.deployment.annotations.metadata.EjbJarAnnotationMetadata; 64 import org.objectweb.easybeans.deployment.annotations.metadata.FieldAnnotationMetadata; 65 import org.objectweb.easybeans.deployment.annotations.metadata.MethodAnnotationMetadata; 66 import org.objectweb.easybeans.deployment.resolver.JNDIResolver; 67 import org.objectweb.easybeans.enhancer.CommonClassGenerator; 68 import org.objectweb.easybeans.enhancer.interceptors.EasyBeansInvocationContextGenerator; 69 import org.objectweb.easybeans.enhancer.lib.MethodRenamer; 70 import org.objectweb.easybeans.injection.JNDILookupHelper.JndiType; 71 import org.objectweb.easybeans.log.JLog; 72 import org.objectweb.easybeans.log.JLogFactory; 73 import org.omg.CORBA.ORB ; 74 75 79 public class InjectionClassAdapter extends ClassAdapter implements Opcodes { 80 81 84 private static JLog logger = JLogFactory.getLog(InjectionClassAdapter.class); 85 86 89 private ClassAnnotationMetadata classAnnotationMetadata; 90 91 94 private Map <String , Object > map = null; 95 96 99 private boolean staticMode = false; 100 101 104 private static final String SESSION_CONTEXT = SessionContext .class.getName(); 105 106 109 private static final String MESSAGEDRIVEN_CONTEXT = MessageDrivenContext .class.getName(); 110 111 114 private static final String ORB_ITF = ORB .class.getName(); 115 116 119 private static final String DATASOURCE_ITF = DataSource .class.getName(); 120 121 124 private static final String USERTRANSACTION_ITF = UserTransaction .class.getName(); 125 126 129 private static final String QUEUE_ITF = Queue .class.getName(); 130 131 134 private static final String QUEUECONNECTIONFACTORY_ITF = QueueConnectionFactory .class.getName(); 135 136 139 private static final String TOPIC_ITF = Topic .class.getName(); 140 141 144 private static final String TOPICCONNECTIONFACTORY_ITF = TopicConnectionFactory .class.getName(); 145 146 149 private static final String ENTITYMANAGER_ITF = EntityManager.class.getName(); 150 151 154 private static final String ENTITYMANAGERFACTORY_ITF = EntityManagerFactory.class.getName(); 155 156 159 private static final String TIMERSERVICE_ITF = TimerService .class.getName(); 160 161 164 private static final String EZB_EJBCONTEXT_DESC = Type.getDescriptor(EZBEJBContext.class); 165 166 169 public static final String JAVA_LANG_OBJECT = "java/lang/Object"; 170 171 174 public static final String INJECTED_METHOD = "injectedByEasyBeans"; 175 176 179 public static final JMethod INJECTED_JMETHOD = new JMethod(ACC_PUBLIC, MethodRenamer.encode(INJECTED_METHOD), "()V", null, 180 new String [] {"org/objectweb/easybeans/api/injection/EasyBeansInjectionException"}); 181 182 185 public static final String [] INJECTED_METHODS = new String [] {"getEasyBeansContext", "setEasyBeansContext", 186 "getEasyBeansFactory", "setEasyBeansFactory"}; 187 188 191 private static final int LENGTH = 3; 192 193 201 public InjectionClassAdapter(final ClassAnnotationMetadata classAnnotationMetadata, final ClassVisitor cv, 202 final Map <String , Object > map, final boolean staticMode) { 203 super(cv); 204 this.classAnnotationMetadata = classAnnotationMetadata; 205 this.map = map; 206 this.staticMode = staticMode; 207 } 208 209 214 @Override 215 public void visitEnd() { 216 super.visitEnd(); 217 218 addInjectedMethod(); 220 221 if (!classAnnotationMetadata.isBean()) { 226 addDefaultMethods(); 227 } 228 } 229 230 234 private void addDefaultMethods() { 235 CommonClassGenerator.addFieldGettersSetters(cv, classAnnotationMetadata.getClassName(), "easyBeansFactory", 237 Factory .class); 238 239 Class contextClass = null; 241 if (classAnnotationMetadata.isSession()) { 242 contextClass = EZBSessionContext.class; 243 } else if (classAnnotationMetadata.isMdb()){ 244 contextClass = EZBMDBContext.class; 245 } else { 246 contextClass = EZBEJBContext.class; 247 } 248 CommonClassGenerator.addFieldGettersSetters(cv, classAnnotationMetadata.getClassName(), 249 "easyBeansContext", contextClass); 250 } 251 252 255 private void addInjectedMethod() { 256 int access = ACC_PUBLIC; 257 if (staticMode) { 258 access = access + ACC_STATIC; 259 } 260 261 MethodVisitor mv = cv.visitMethod(access, INJECTED_METHOD, "()V", null, 262 new String [] {"org/objectweb/easybeans/api/injection/EasyBeansInjectionException"}); 263 mv.visitCode(); 264 265 String superNameClass = classAnnotationMetadata.getSuperName(); 268 if (superNameClass != null && !superNameClass.equals(JAVA_LANG_OBJECT)) { 269 EjbJarAnnotationMetadata jarMetadata = classAnnotationMetadata.getEjbJarAnnotationMetadata(); 270 ClassAnnotationMetadata superMetadata = jarMetadata.getClassAnnotationMetadata(superNameClass); 271 if (superMetadata != null) { 272 if (!staticMode) { 273 mv.visitVarInsn(ALOAD, 0); 275 mv.visitMethodInsn(INVOKESPECIAL, superMetadata.getClassName(), INJECTED_METHOD, "()V"); 276 } else { 277 mv.visitMethodInsn(INVOKESTATIC, superMetadata.getClassName(), INJECTED_METHOD, "()V"); 278 } 279 } 280 } 281 282 if (classAnnotationMetadata.isBean()) { 284 String clNameManager = classAnnotationMetadata.getClassName() 285 + EasyBeansInvocationContextGenerator.SUFFIX_INTERCEPTOR_MANAGER; 286 287 mv.visitVarInsn(ALOAD, 0); 289 mv.visitFieldInsn(GETFIELD, classAnnotationMetadata.getClassName(), "easyBeansInterceptorManager", "L" 290 + clNameManager + ";"); 291 mv.visitVarInsn(ALOAD, 0); 292 mv.visitFieldInsn(GETFIELD, classAnnotationMetadata.getClassName(), "easyBeansContext", EZB_EJBCONTEXT_DESC); 293 mv.visitMethodInsn(INVOKEVIRTUAL, clNameManager, "setEasyBeansContext", "(" + EZB_EJBCONTEXT_DESC + ")V"); 294 295 296 mv.visitVarInsn(ALOAD, 0); 298 mv.visitFieldInsn(GETFIELD, classAnnotationMetadata.getClassName(), "easyBeansInterceptorManager", "L" 299 + clNameManager + ";"); 300 mv.visitMethodInsn(INVOKEVIRTUAL, clNameManager, "injectedByEasyBeans", "()V"); 301 302 } 303 304 generateBodyInjectedMethod(mv); 305 306 mv.visitInsn(RETURN); 307 mv.visitMaxs(0, 0); 308 mv.visitEnd(); 309 } 310 311 316 private void generateBodyInjectedMethod(final MethodVisitor mv) { 317 318 generateClassInjection(mv); 320 321 generateAttributesInjection(mv); 323 324 generateSettersInjection(mv); 326 327 } 328 329 333 private void generateClassInjection(final MethodVisitor mv) { 334 336 List <JavaxPersistenceContext> javaxPersistencePersistenceContexts = classAnnotationMetadata 338 .getJavaxPersistencePersistenceContexts(); 339 if (javaxPersistencePersistenceContexts != null && javaxPersistencePersistenceContexts.size() > 0) { 340 for (JavaxPersistenceContext javaxPersistenceContext : javaxPersistencePersistenceContexts) { 342 bindClassPersistenceContext(javaxPersistenceContext, mv); 343 } 344 } 345 if (classAnnotationMetadata.isPersistenceContext()) { 347 bindClassPersistenceContext(classAnnotationMetadata.getJavaxPersistenceContext(), mv); 348 } 349 350 List <JavaxPersistenceUnit> javaxPersistencePersistenceUnits = classAnnotationMetadata 352 .getJavaxPersistencePersistenceUnits(); 353 if (javaxPersistencePersistenceUnits != null && javaxPersistencePersistenceUnits.size() > 0) { 354 for (JavaxPersistenceUnit javaxPersistenceUnit : javaxPersistencePersistenceUnits) { 356 bindClassPersistenceUnit(javaxPersistenceUnit, mv); 357 } 358 } 359 if (classAnnotationMetadata.isPersistenceUnit()) { 361 bindClassPersistenceUnit(classAnnotationMetadata.getJavaxPersistenceUnit(), mv); 362 } 363 364 List <JEjbEJB> jEjbs = classAnnotationMetadata.getJEjbEJBs(); 366 if (jEjbs != null && jEjbs.size() > 0) { 367 for (JEjbEJB jEJB : jEjbs) { 369 bindClassEJB(jEJB, mv); 370 } 371 } 372 JEjbEJB jEJB = classAnnotationMetadata.getJEjbEJB(); 374 if (jEJB != null) { 375 bindClassEJB(jEJB, mv); 377 } 378 379 380 List <JAnnotationResource> jAnnotationResources = classAnnotationMetadata.getJAnnotationResources(); 382 if (jAnnotationResources != null && jAnnotationResources.size() > 0) { 383 for (JAnnotationResource jAnnotationResource : jAnnotationResources) { 385 bindResource(jAnnotationResource, mv); 386 } 387 } 388 JAnnotationResource jAnnotationResource = classAnnotationMetadata.getJAnnotationResource(); 390 if (jAnnotationResource != null) { 391 bindResource(jAnnotationResource, mv); 392 } 393 394 395 } 396 397 398 402 private void generateAttributesInjection(final MethodVisitor mv) { 403 404 for (FieldAnnotationMetadata fieldMetaData : classAnnotationMetadata.getFieldAnnotationMetadataCollection()) { 405 406 Type typeInterface = Type.getType(fieldMetaData.getJField().getDescriptor()); 408 String itfName = typeInterface.getClassName(); 409 410 if (fieldMetaData.isPersistenceContext()) { 412 validateAccessFieldAnnotation(fieldMetaData); 414 415 if (!ENTITYMANAGER_ITF.equals(itfName)) { 417 throw new IllegalStateException ( 418 "Trying to applied @PersistenceContext on an invalid field in the class '" 419 + classAnnotationMetadata.getClassName() + "', field = " + fieldMetaData); 420 } 421 422 JavaxPersistenceContext javaxPersistenceContext = fieldMetaData.getJavaxPersistenceContext(); 423 424 logger.debug("Add injection for PersistenceContext on attribute {0} of class {1}", fieldMetaData 425 .getFieldName(), classAnnotationMetadata.getClassName()); 426 mv.visitVarInsn(ALOAD, 0); 430 431 432 addCallEntityManagerHelper(javaxPersistenceContext, mv); 434 435 mv.visitFieldInsn(PUTFIELD, classAnnotationMetadata.getClassName(), fieldMetaData.getFieldName(), 437 "Ljavax/persistence/EntityManager;"); 438 439 javaxPersistenceContext.setName(getJndiName(javaxPersistenceContext.getName(), fieldMetaData)); 441 bindClassPersistenceContext(javaxPersistenceContext, mv); 442 443 } 444 445 if (fieldMetaData.isPersistenceUnit()) { 447 validateAccessFieldAnnotation(fieldMetaData); 449 450 if (!ENTITYMANAGERFACTORY_ITF.equals(itfName)) { 452 throw new IllegalStateException ( 453 "Trying to applied @PersistenceUnit on an invalid field in the class '" 454 + classAnnotationMetadata.getClassName() + "', field = " + fieldMetaData); 455 } 456 logger.debug("Add injection for PersistenceUnit on attribute {0} of class {1}", fieldMetaData 457 .getFieldName(), classAnnotationMetadata.getClassName()); 458 459 460 JavaxPersistenceUnit javaxPersistenceUnit = fieldMetaData.getJavaxPersistenceUnit(); 461 463 mv.visitVarInsn(ALOAD, 0); 464 addCallEntityManagerFactoryHelper(javaxPersistenceUnit, mv); 466 mv.visitFieldInsn(PUTFIELD, classAnnotationMetadata.getClassName(), fieldMetaData.getFieldName(), 468 "Ljavax/persistence/EntityManagerFactory;"); 469 470 javaxPersistenceUnit.setName(getJndiName(javaxPersistenceUnit.getName(), fieldMetaData)); 472 bindClassPersistenceUnit(javaxPersistenceUnit, mv); 473 } 474 475 JEjbEJB jEjb = fieldMetaData.getJEjbEJB(); 477 if (jEjb != null) { 478 validateAccessFieldAnnotation(fieldMetaData); 480 481 logger.debug("Add injection for EJB on attribute {0} of class {1}", fieldMetaData.getFieldName(), 482 classAnnotationMetadata.getClassName()); 483 484 JNDIResolver jndiResolver = (JNDIResolver) map.get(JNDIResolver.NAME); 485 String beanName = jEjb.getBeanName(); 487 String jndiName = jndiResolver.getJndiNameInterface(itfName, beanName); 488 489 if (jndiName == null) { 490 logger.error("No jndi name found on class {0} for interface {1} and beanName {2}", 491 classAnnotationMetadata.getClassName(), itfName, beanName); 492 } else { 493 logger.debug("Asking jndi name on class {0} for interface {1} and beanName {2}. Result = {3}", 494 classAnnotationMetadata.getClassName(), itfName, beanName, jndiName); 495 callAttributeJndi(jndiName, typeInterface, mv, fieldMetaData, classAnnotationMetadata 496 .getClassName(), REGISTRY); 497 callBindAttributeJndi(jEjb.getName(), jndiName, mv, fieldMetaData); 498 } 499 } 500 501 JAnnotationResource jAnnotationResource = fieldMetaData.getJAnnotationResource(); 503 if (jAnnotationResource != null) { 504 String mappedName = jAnnotationResource.getMappedName(); 505 506 validateAccessFieldAnnotation(fieldMetaData); 508 509 if (SESSION_CONTEXT.equals(itfName)) { 510 logger.debug("Add injection for @Resource on attribute {0} of class {1} for the type {2}", 511 fieldMetaData.getFieldName(), classAnnotationMetadata.getClassName(), itfName); 512 513 mv.visitVarInsn(ALOAD, 0); 515 addCallGetEasyBeansContext(mv, "javax/ejb/SessionContext"); 516 mv.visitFieldInsn(PUTFIELD, classAnnotationMetadata.getClassName(), fieldMetaData.getFieldName(), 517 "Ljavax/ejb/SessionContext;"); 518 jAnnotationResource.setType(SESSION_CONTEXT); 520 521 jAnnotationResource.setName(getJndiName(jAnnotationResource.getName(), fieldMetaData)); 523 524 bindResource(jAnnotationResource, mv); 525 } else if (MESSAGEDRIVEN_CONTEXT.equals(itfName)) { 526 logger.debug("Add injection for @Resource on attribute {0} of class {1} for the type {2}", 527 fieldMetaData.getFieldName(), classAnnotationMetadata.getClassName(), itfName); 528 529 mv.visitVarInsn(ALOAD, 0); 531 addCallGetEasyBeansContext(mv, "javax/ejb/MessageDrivenContext"); 532 mv.visitFieldInsn(PUTFIELD, classAnnotationMetadata.getClassName(), fieldMetaData.getFieldName(), 533 "Ljavax/ejb/MessageDrivenContext;"); 534 jAnnotationResource.setType(MESSAGEDRIVEN_CONTEXT); 536 537 jAnnotationResource.setName(getJndiName(jAnnotationResource.getName(), fieldMetaData)); 539 540 bindResource(jAnnotationResource, mv); 541 542 } else if (isEnvEntry(typeInterface)) { callAttributeJndi(jAnnotationResource.getName(), typeInterface, mv, fieldMetaData, 544 classAnnotationMetadata.getClassName(), JAVA_COMP_ENV); 545 } else if (isJNDIResourceInjection(itfName)) { 546 if (mappedName != null && !mappedName.equals("")) { 547 callAttributeJndi(mappedName, typeInterface, mv, fieldMetaData, 548 classAnnotationMetadata.getClassName(), REGISTRY); 549 callBindAttributeJndi(jAnnotationResource.getName(), mappedName, mv, fieldMetaData); 550 } else { 551 callAttributeJndi(jAnnotationResource.getName(), typeInterface, mv, fieldMetaData, 553 classAnnotationMetadata.getClassName(), REGISTRY); 554 } 555 } else if (USERTRANSACTION_ITF.equals(itfName)) { 556 callAttributeJndi("UserTransaction", typeInterface, mv, fieldMetaData, 557 classAnnotationMetadata.getClassName(), JAVA_COMP); 558 } else if (TIMERSERVICE_ITF.equals(itfName)) { 559 mv.visitVarInsn(ALOAD, 0); 562 addCallGetEasyBeansContext(mv, null); 563 mv.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(EZBEJBContext.class), "getTimerService", 564 "()Ljavax/ejb/TimerService;"); 565 mv.visitFieldInsn(PUTFIELD, classAnnotationMetadata.getClassName(), fieldMetaData.getFieldName(), 566 "Ljavax/ejb/TimerService;"); 567 } else if (ORB_ITF.equals(itfName)) { 568 if (!staticMode) { 570 mv.visitVarInsn(ALOAD, 0); 571 } 572 mv.visitMethodInsn(INVOKESTATIC, "org/objectweb/easybeans/injection/ORBInitHelper", "getORB", 573 "()Lorg/omg/CORBA/ORB;"); 574 mv.visitFieldInsn(setField(), classAnnotationMetadata.getClassName(), fieldMetaData.getFieldName(), 575 "Lorg/omg/CORBA/ORB;"); 576 577 } 578 579 } 580 581 } 582 } 583 584 588 private void generateSettersInjection(final MethodVisitor mv) { 589 590 for (MethodAnnotationMetadata methodMetaData : classAnnotationMetadata.getMethodAnnotationMetadataCollection()) { 591 if (methodMetaData.isInherited()) { 593 continue; 594 } 595 596 JAnnotationResource jAnnotationResource = methodMetaData.getJAnnotationResource(); 597 if (jAnnotationResource != null) { 599 Type typeInterface = validateSetterMethod(methodMetaData); 600 String itfName = typeInterface.getClassName(); 601 602 if (isEnvEntry(typeInterface)) { 604 callMethodJndiEnv(jAnnotationResource.getName(), typeInterface, mv, methodMetaData, 605 classAnnotationMetadata.getClassName(), JAVA_COMP_ENV); 606 } else if (isJNDIResourceInjection(itfName)) { 607 callMethodJndiEnv(jAnnotationResource.getName(), typeInterface, mv, methodMetaData, 609 classAnnotationMetadata.getClassName(), REGISTRY); 610 } else if (USERTRANSACTION_ITF.equals(itfName)) { 611 callMethodJndiEnv("UserTransaction", typeInterface, mv, methodMetaData, 612 classAnnotationMetadata.getClassName(), JAVA_COMP); 613 } else if (SESSION_CONTEXT.equals(itfName)) { 614 mv.visitVarInsn(ALOAD, 0); 616 addCallGetEasyBeansContext(mv, "javax/ejb/SessionContext"); 617 mv.visitMethodInsn(INVOKEVIRTUAL, classAnnotationMetadata.getClassName(), methodMetaData.getMethodName(), 618 "(Ljavax/ejb/SessionContext;)V"); 619 620 jAnnotationResource.setType(SESSION_CONTEXT); 622 jAnnotationResource.setName(getJndiName(jAnnotationResource.getName(), methodMetaData)); 624 bindResource(jAnnotationResource, mv); 625 } else if (MESSAGEDRIVEN_CONTEXT.equals(itfName)) { 626 mv.visitVarInsn(ALOAD, 0); 628 addCallGetEasyBeansContext(mv, "javax/ejb/MessageDrivenContext"); 629 mv.visitMethodInsn(INVOKEVIRTUAL, classAnnotationMetadata.getClassName(), methodMetaData.getMethodName(), 630 "(Ljavax/ejb/MessageDrivenContext;)V"); 631 632 jAnnotationResource.setType(MESSAGEDRIVEN_CONTEXT); 634 jAnnotationResource.setName(getJndiName(jAnnotationResource.getName(), methodMetaData)); 636 bindResource(jAnnotationResource, mv); 637 } 638 } 639 640 JEjbEJB jEjb = methodMetaData.getJEjbEJB(); 642 if (jEjb != null) { 643 logger.debug("Add injection for EJB on method {0} of class {1}", methodMetaData.getMethodName(), 644 classAnnotationMetadata.getClassName()); 645 646 Type typeInterface = validateSetterMethod(methodMetaData); 647 String itfName = typeInterface.getClassName(); 648 649 JNDIResolver jndiResolver = (JNDIResolver) map.get(JNDIResolver.NAME); 650 String beanName = jEjb.getBeanName(); 652 String jndiName = jndiResolver.getJndiNameInterface(itfName, beanName); 653 logger.debug("Asking jndi name on class {0} for interface {1} and beanName {2}. Result = {3}", 654 classAnnotationMetadata.getClassName(), itfName, beanName, jndiName); 655 656 callMethodJndiEnv(jndiName, typeInterface, mv, methodMetaData, classAnnotationMetadata.getClassName(), REGISTRY); 657 658 String encName = getJndiName(jEjb.getName(), methodMetaData); 660 callBindLookupJndiRef(encName, jndiName, mv); 661 } 662 663 if (methodMetaData.isPersistenceContext()) { 665 Type typeInterface = validateSetterMethod(methodMetaData); 666 String itfName = typeInterface.getClassName(); 667 668 if (!ENTITYMANAGER_ITF.equals(itfName)) { 670 throw new IllegalStateException ( 671 "Trying to applied @PersistenceContext on an invalid method in the class '" 672 + classAnnotationMetadata.getClassName() + "', method = " + methodMetaData); 673 } 674 logger.debug("Add injection for PersistenceContext on method {0} of class {1}", methodMetaData 675 .getMethodName(), classAnnotationMetadata.getClassName()); 676 677 JavaxPersistenceContext javaxPersistenceContext = methodMetaData.getJavaxPersistenceContext(); 678 682 mv.visitVarInsn(ALOAD, 0); 683 684 addCallEntityManagerHelper(javaxPersistenceContext, mv); 686 687 mv.visitMethodInsn(INVOKEVIRTUAL, classAnnotationMetadata.getClassName(), methodMetaData 689 .getMethodName(), "(Ljavax/persistence/EntityManager;)V"); 690 691 692 javaxPersistenceContext.setName(getJndiName(javaxPersistenceContext.getName(), methodMetaData)); 694 bindClassPersistenceContext(javaxPersistenceContext, mv); 695 696 697 } 698 699 if (methodMetaData.isPersistenceUnit()) { 701 Type typeInterface = validateSetterMethod(methodMetaData); 702 String itfName = typeInterface.getClassName(); 703 if (!ENTITYMANAGERFACTORY_ITF.equals(itfName)) { 705 throw new IllegalStateException ( 706 "Trying to applied @PersistenceUnit on an invalid method in the class '" 707 + classAnnotationMetadata.getClassName() + "', method = " + methodMetaData); 708 } 709 logger.debug("Add injection for PersistenceUnit on on method {0} of class {1}", methodMetaData 710 .getMethodName(), classAnnotationMetadata.getClassName()); 711 712 JavaxPersistenceUnit javaxPersistenceUnit = methodMetaData.getJavaxPersistenceUnit(); 713 714 718 mv.visitVarInsn(ALOAD, 0); 719 addCallEntityManagerFactoryHelper(javaxPersistenceUnit, mv); 721 mv.visitMethodInsn(INVOKEVIRTUAL, classAnnotationMetadata.getClassName(), methodMetaData 723 .getMethodName(), "(Ljavax/persistence/EntityManagerFactory;)V"); 724 725 javaxPersistenceUnit.setName(getJndiName(javaxPersistenceUnit.getName(), methodMetaData)); 727 bindClassPersistenceUnit(javaxPersistenceUnit, mv); 728 } 729 730 } 731 } 732 733 734 739 private Type validateSetterMethod(final MethodAnnotationMetadata methodMetaData) { 740 validateAccessMethodAnnotation(methodMetaData); 742 743 JMethod jMethod = methodMetaData.getJMethod(); 744 if (!jMethod.getName().startsWith("set") || jMethod.getName().equalsIgnoreCase("set")) { 746 throw new IllegalStateException ("Method '" + jMethod 747 + "' is invalid. Should be in the setter form setXXX()."); 748 } 749 750 Type[] args = Type.getArgumentTypes(jMethod.getDescriptor()); 753 if (args.length != 1) { 754 throw new IllegalStateException ("Method args '" + Arrays.asList(args) + "' for method '" + jMethod 755 + "' are invalid. Length should be of 1."); 756 } 757 return args[0]; 758 } 759 760 765 private boolean isEnvEntry(final Type type) { 766 String itfName = type.getClassName(); 767 return String .class.getName().equals(itfName) || Boolean.TYPE.getName().equals(itfName) 768 || Byte.TYPE.getName().equals(itfName) || Character.TYPE.getName().equals(itfName) 769 || Double.TYPE.getName().equals(itfName) || Float.TYPE.getName().equals(itfName) 770 || Integer.TYPE.getName().equals(itfName) || Long.TYPE.getName().equals(itfName) 771 || Short.TYPE.getName().equals(itfName); 772 } 773 774 779 private void addCallGetEasyBeansContext(final MethodVisitor mv, final String castDesc) { 780 mv.visitVarInsn(ALOAD, 0); 781 mv.visitMethodInsn(INVOKEVIRTUAL, classAnnotationMetadata.getClassName(), 782 "getEasyBeansContext", "()" + EZB_EJBCONTEXT_DESC); 783 if (castDesc != null) { 784 mv.visitTypeInsn(CHECKCAST, castDesc); 785 } 786 } 787 788 795 private void addCallEntityManagerHelper(final JavaxPersistenceContext javaxPersistenceContext, final MethodVisitor mv) { 796 addCallGetEasyBeansContext(mv, null); 798 799 mv.visitLdcInsn(javaxPersistenceContext.getUnitName()); 801 802 mv.visitFieldInsn(GETSTATIC, "javax/persistence/PersistenceContextType", javaxPersistenceContext.getType().toString(), 804 "Ljavax/persistence/PersistenceContextType;"); 805 mv 807 .visitMethodInsn( 808 INVOKESTATIC, 809 "org/objectweb/easybeans/injection/EntityManagerHelper", 810 "getEntityManager", 811 "(" + EZB_EJBCONTEXT_DESC 812 + "Ljava/lang/String;Ljavax/persistence/PersistenceContextType;)" 813 + "Ljavax/persistence/EntityManager;"); 814 } 815 816 822 private void addCallEntityManagerFactoryHelper(final JavaxPersistenceUnit javaxPersistenceUnit, final MethodVisitor mv) { 823 addCallGetEasyBeansContext(mv, null); 825 826 mv.visitLdcInsn(javaxPersistenceUnit.getUnitName()); 828 829 mv.visitMethodInsn(INVOKESTATIC, "org/objectweb/easybeans/injection/EntityManagerHelper", 830 "getEntityManagerFactory", 831 "(" + EZB_EJBCONTEXT_DESC 832 + "Ljava/lang/String;)Ljavax/persistence/EntityManagerFactory;"); 833 } 834 835 836 845 private void callJndi(final String jndiName, final Type type, final MethodVisitor mv, 846 final String className, final JndiType jndiType) { 847 if (!staticMode) { 848 mv.visitVarInsn(ALOAD, 0); 849 } 850 mv.visitLdcInsn(jndiName); 851 String mName = ""; 852 switch (jndiType) { 853 case JAVA_COMP: 854 mName = "getCompJndiName"; 855 break; 856 case JAVA_COMP_ENV: 857 mName = "getEnvJndiName"; 858 break; 859 case REGISTRY: 860 mName = "getJndiName"; 861 break; 862 default: 863 throw new IllegalStateException ("invalid type"); 864 } 865 mv.visitMethodInsn(INVOKESTATIC, "org/objectweb/easybeans/injection/JNDILookupHelper", mName, 866 "(Ljava/lang/String;)Ljava/lang/Object;"); 867 CommonClassGenerator.transformObjectIntoPrimitive(type, mv); 868 } 869 870 880 private void callAttributeJndi(final String jndiName, final Type type, final MethodVisitor mv, 881 final FieldAnnotationMetadata fieldMetaData, final String className, final JndiType jndiType) { 882 logger.debug("Add injection for @Resource on attribute {0} of class {1} for the type {2}", fieldMetaData 883 .getFieldName(), className, type.getClassName()); 884 885 String formattedJndiName = getJndiName(jndiName, fieldMetaData); 886 callJndi(formattedJndiName, type, mv, className, jndiType); 887 setField(mv, className, fieldMetaData, type); 888 } 889 890 897 private void setField(final MethodVisitor mv, final String className, 898 final FieldAnnotationMetadata fieldMetaData, final Type type) { 899 mv.visitFieldInsn(setField(), className, fieldMetaData.getFieldName(), type.getDescriptor()); 900 } 901 902 909 private void callSetterMethod(final MethodVisitor mv, final String className, 910 final MethodAnnotationMetadata methodMetaData, final Type type) { 911 mv.visitMethodInsn(INVOKEVIRTUAL, className, methodMetaData.getMethodName(), methodMetaData.getJMethod() 912 .getDescriptor()); 913 } 914 915 916 926 private void callMethodJndiEnv(final String jndiName, final Type type, final MethodVisitor mv, 927 final MethodAnnotationMetadata methodMetaData, final String className, final JndiType jndiType) { 928 logger.debug("Add injection for @Resource on method {0} of class {1} for the type {2}", methodMetaData 929 .getMethodName(), className, type.getClassName()); 930 931 String checkedJndiName = getJndiName(jndiName, methodMetaData); 932 callJndi(checkedJndiName, type, mv, className, jndiType); 933 callSetterMethod(mv, className, methodMetaData, type); 934 } 935 936 937 943 private String getJndiName(final String jndiName, final FieldAnnotationMetadata fieldAnnotationMetadata) { 944 String newJndiName = jndiName; 945 if (jndiName == null || "".equals(jndiName)) { 946 logger.debug("Name property undefined."); 947 newJndiName = classAnnotationMetadata.getClassName().replace("/", ".") + "/" + fieldAnnotationMetadata.getFieldName(); 948 logger.debug("Getting environment's entry with default JNDI name: {0}", newJndiName); 949 } 950 return newJndiName; 951 } 952 953 954 960 private String getJndiName(final String jndiName, final MethodAnnotationMetadata methodMetaData) { 961 String newJndiName = jndiName; 962 if (jndiName == null || "".equals(jndiName)) { 963 logger.debug("Property name not defined."); 964 StringBuilder propertyBuilder = new StringBuilder (methodMetaData.getMethodName()); 965 propertyBuilder.delete(0, LENGTH); 966 propertyBuilder.setCharAt(0, Character.toLowerCase(propertyBuilder.charAt(0))); 967 propertyBuilder.insert(0, classAnnotationMetadata.getClassName().replace("/", ".") + "/"); 968 newJndiName = propertyBuilder.toString(); 969 logger.debug("Getting environment's entry with default JNDI name: {0}", newJndiName); 970 } 971 972 return newJndiName; 973 } 974 975 976 984 private void callBindAttributeJndi(final String encName, final String jndiName, final MethodVisitor mv, 985 final FieldAnnotationMetadata fieldMetaData) { 986 987 988 mv.visitLdcInsn(getJndiName(encName, fieldMetaData)); 990 mv.visitLdcInsn(jndiName); 991 mv.visitMethodInsn(INVOKESTATIC, "org/objectweb/easybeans/injection/JNDIBinderHelper", 992 "bindLinkRefEnvJndiName", "(Ljava/lang/String;Ljava/lang/String;)V"); 993 } 994 995 996 1003 private void callBindLookupJndiRef(final String encName, final String jndiName, final MethodVisitor mv) { 1004 1007 mv.visitLdcInsn(encName); 1008 mv.visitLdcInsn(jndiName); 1009 mv.visitMethodInsn(INVOKESTATIC, "org/objectweb/easybeans/injection/JNDIBinderHelper", 1010 "bindLinkRefEnvJndiName", "(Ljava/lang/String;Ljava/lang/String;)V"); 1011 1012 logger.debug("Linking Object with JNDI name '" + jndiName + "' to ENC name '" + encName + "' for the class '" 1013 + classAnnotationMetadata.getClassName() + "'."); 1014 } 1015 1016 1017 1022 private void bindClassEJB(final JEjbEJB jEJB, final MethodVisitor mv) { 1023 1024 1027 1028 String encName = jEJB.getName(); 1030 if (encName == null || "".equals(encName)) { 1031 throw new IllegalStateException ("Error when analyzing @EJB annotation '" + jEJB 1032 + "' for the class '" + classAnnotationMetadata.getClassName() + "' : No name !"); 1033 } 1034 1035 JNDIResolver jndiResolver = (JNDIResolver) map.get(JNDIResolver.NAME); 1037 String beanName = jEJB.getBeanName(); 1039 String jndiName = null; 1040 if (jEJB.getMappedName() != null && jEJB.getMappedName().length() > 0) { 1041 jndiName = jEJB.getMappedName(); 1042 } else { 1043 jndiName = jndiResolver.getJndiNameInterface(jEJB.getBeanInterface(), beanName); 1044 } 1045 1046 if (jndiName == null) { 1047 throw new IllegalStateException ("No JNDI name found when analyzing @EJB annotation '" + jEJB 1048 + "' for the class '" + classAnnotationMetadata.getClassName() + "'."); 1049 } 1050 1051 callBindLookupJndiRef(encName, jndiName, mv); 1053 } 1054 1055 1060 private void bindResource(final JAnnotationResource jAnnotationResource, final MethodVisitor mv) { 1061 if (DATASOURCE_ITF.equals(jAnnotationResource.getType()) 1062 || SESSION_CONTEXT.equals(jAnnotationResource.getType())) { 1063 String encName = jAnnotationResource.getName(); 1065 if (encName == null || "".equals(encName)) { 1066 logger.error("No encName for Annotation resource {0}.", jAnnotationResource); 1067 return; 1068 } 1069 String jndiName = null; 1070 if (SESSION_CONTEXT.equals(jAnnotationResource.getType())) { 1071 jndiName = "java:comp/EJBContext"; 1072 } else { 1073 jndiName = jAnnotationResource.getMappedName(); 1074 } 1075 if (jndiName == null) { 1076 logger.error("JndiName for resource annotation {0} is null, no binding to ENC name {1}", 1077 jAnnotationResource, encName); 1078 } else { 1079 callBindLookupJndiRef(encName, jndiName, mv); 1081 } 1082 } 1083 } 1084 1085 1086 1091 private void bindClassPersistenceContext(final JavaxPersistenceContext javaxPersistenceContext, final MethodVisitor mv) { 1092 1093 1096 String name = javaxPersistenceContext.getName(); 1098 if (name == null || "".equals(name)) { 1099 logger.warn("PersistenceContext '" + javaxPersistenceContext + "' has an empty or null name, cannot bind it in ENC."); 1100 return; 1101 } 1102 1103 mv.visitLdcInsn(name); 1105 1106 addCallEntityManagerHelper(javaxPersistenceContext, mv); 1108 1109 mv.visitMethodInsn(INVOKESTATIC, "org/objectweb/easybeans/injection/JNDIBinderHelper", "bindEnvJndiName", 1111 "(Ljava/lang/String;Ljava/lang/Object;)V"); 1112 } 1113 1114 1115 1120 private void bindClassPersistenceUnit(final JavaxPersistenceUnit javaxPersistenceUnit, final MethodVisitor mv) { 1121 1124 String name = javaxPersistenceUnit.getName(); 1126 if (name == null || "".equals(name)) { 1127 logger.warn("PersistenceUnit '" + javaxPersistenceUnit + "' has an empty or null name, cannot bind it in ENC."); 1128 return; 1129 } 1130 1131 mv.visitLdcInsn(name); 1133 1134 addCallEntityManagerFactoryHelper(javaxPersistenceUnit, mv); 1136 1137 mv.visitMethodInsn(INVOKESTATIC, "org/objectweb/easybeans/injection/JNDIBinderHelper", "bindEnvJndiName", 1139 "(Ljava/lang/String;Ljava/lang/Object;)V"); 1140 } 1141 1142 1143 1146 private int setField() { 1147 int opCode = PUTFIELD; 1148 if (staticMode) { 1149 opCode = PUTSTATIC; 1150 } 1151 return opCode; 1152 } 1153 1154 1159 private void validateAccessFieldAnnotation(final FieldAnnotationMetadata field) { 1160 if (accessTest(field.getJField().getAccess(), ACC_FINAL)) { 1161 throw new IllegalStateException ("The '" + field 1162 + "' attribute is a final attribute which is not compliant for dependency injection."); 1163 } 1164 if (!staticMode && accessTest(field.getJField().getAccess(), ACC_STATIC)) { 1165 throw new IllegalStateException ("The '" + field 1166 + "' attribute is a static attribute which is not compliant for dependency injection."); 1167 } 1168 } 1169 1170 1175 private void validateAccessMethodAnnotation(final MethodAnnotationMetadata methodData) { 1176 if (!staticMode && accessTest(methodData.getJMethod().getAccess(), ACC_STATIC)) { 1177 throw new IllegalStateException ("The '" + methodData 1178 + "' method is a static attribute which is not compliant for dependency injection."); 1179 } 1180 } 1181 1182 1183 1188 private boolean accessTest(final int access, final int checkedAccess) { 1189 return (access & checkedAccess) == checkedAccess; 1190 } 1191 1192 1198 private boolean isJNDIResourceInjection(final String itfName) { 1199 return DATASOURCE_ITF.equals(itfName) || QUEUE_ITF.equals(itfName) || QUEUECONNECTIONFACTORY_ITF.equals(itfName) 1200 || TOPIC_ITF.equals(itfName) || TOPICCONNECTIONFACTORY_ITF.equals(itfName); 1201 } 1202} 1203 | Popular Tags |