KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > easybeans > enhancer > injection > InjectionClassAdapter


1 /**
2  * EasyBeans
3  * Copyright (C) 2006 Bull S.A.S.
4  * Contact: easybeans@objectweb.org
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19  * USA
20  *
21  * --------------------------------------------------------------------------
22  * $Id: InjectionClassAdapter.java 1131 2006-09-29 13:42:59Z benoitf $
23  * --------------------------------------------------------------------------
24  */

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 JavaDoc;
33 import java.util.List JavaDoc;
34 import java.util.Map JavaDoc;
35
36 import javax.ejb.MessageDrivenContext JavaDoc;
37 import javax.ejb.SessionContext JavaDoc;
38 import javax.ejb.TimerService JavaDoc;
39 import javax.jms.Queue JavaDoc;
40 import javax.jms.QueueConnectionFactory JavaDoc;
41 import javax.jms.Topic JavaDoc;
42 import javax.jms.TopicConnectionFactory JavaDoc;
43 import javax.persistence.EntityManager;
44 import javax.persistence.EntityManagerFactory;
45 import javax.sql.DataSource JavaDoc;
46 import javax.transaction.UserTransaction JavaDoc;
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 JavaDoc;
74
75 /**
76  * This class adds methods which will inject resources in the bean class.
77  * @author Florent Benoit
78  */

79 public class InjectionClassAdapter extends ClassAdapter implements Opcodes {
80
81     /**
82      * Logger.
83      */

84     private static JLog logger = JLogFactory.getLog(InjectionClassAdapter.class);
85
86     /**
87      * Metadata available by this adapter for a class.
88      */

89     private ClassAnnotationMetadata classAnnotationMetadata;
90
91     /**
92      * Map containing informations for enhancers.
93      */

94     private Map JavaDoc<String JavaDoc, Object JavaDoc> map = null;
95
96     /**
97      * Is that generated method is static (client case).
98      */

99     private boolean staticMode = false;
100
101     /**
102      * javax.ejb.SessionContext interface.
103      */

104     private static final String JavaDoc SESSION_CONTEXT = SessionContext JavaDoc.class.getName();
105
106     /**
107      * javax.ejb.MessageDrivenContext interface.
108      */

109     private static final String JavaDoc MESSAGEDRIVEN_CONTEXT = MessageDrivenContext JavaDoc.class.getName();
110
111     /**
112      * org.omg.CORBA.ORB interface.
113      */

114     private static final String JavaDoc ORB_ITF = ORB JavaDoc.class.getName();
115
116     /**
117      * javax.sql.DataSource interface.
118      */

119     private static final String JavaDoc DATASOURCE_ITF = DataSource JavaDoc.class.getName();
120
121     /**
122      * javax.transaction.UserTransaction interface.
123      */

124     private static final String JavaDoc USERTRANSACTION_ITF = UserTransaction JavaDoc.class.getName();
125
126     /**
127      * javax.jms.Queue interface.
128      */

129     private static final String JavaDoc QUEUE_ITF = Queue JavaDoc.class.getName();
130
131     /**
132      * javax.jms.QueueConnectionFactory interface.
133      */

134     private static final String JavaDoc QUEUECONNECTIONFACTORY_ITF = QueueConnectionFactory JavaDoc.class.getName();
135
136     /**
137      * javax.jms.Topic interface.
138      */

139     private static final String JavaDoc TOPIC_ITF = Topic JavaDoc.class.getName();
140
141     /**
142      * javax.jms.TopicConnectionFactory interface.
143      */

144     private static final String JavaDoc TOPICCONNECTIONFACTORY_ITF = TopicConnectionFactory JavaDoc.class.getName();
145
146     /**
147      * Entity Manager interface.
148      */

149     private static final String JavaDoc ENTITYMANAGER_ITF = EntityManager.class.getName();
150
151     /**
152      * Entity Manager Factory interface.
153      */

154     private static final String JavaDoc ENTITYMANAGERFACTORY_ITF = EntityManagerFactory.class.getName();
155
156     /**
157      * javax.ejb.TimerService interface.
158      */

159     private static final String JavaDoc TIMERSERVICE_ITF = TimerService JavaDoc.class.getName();
160
161     /**
162      * EZBEJBContext type descriptor.
163      */

164     private static final String JavaDoc EZB_EJBCONTEXT_DESC = Type.getDescriptor(EZBEJBContext.class);
165
166     /**
167      * Defines java.lang.Object class.
168      */

169     public static final String JavaDoc JAVA_LANG_OBJECT = "java/lang/Object";
170
171     /**
172      * Injected method name.
173      */

174     public static final String JavaDoc INJECTED_METHOD = "injectedByEasyBeans";
175
176     /**
177      * JMethod object for injectedByEasyBeans.
178      */

179     public static final JMethod INJECTED_JMETHOD = new JMethod(ACC_PUBLIC, MethodRenamer.encode(INJECTED_METHOD), "()V", null,
180             new String JavaDoc[] {"org/objectweb/easybeans/api/injection/EasyBeansInjectionException"});
181
182     /**
183      * List of injected methods.
184      */

185     public static final String JavaDoc[] INJECTED_METHODS = new String JavaDoc[] {"getEasyBeansContext", "setEasyBeansContext",
186             "getEasyBeansFactory", "setEasyBeansFactory"};
187
188     /**
189      * Replace length to create default JNDI names.
190      */

191     private static final int LENGTH = 3;
192
193     /**
194      * Constructor.
195      * @param classAnnotationMetadata object containing all attributes of the
196      * class
197      * @param cv the class visitor to which this adapter must delegate calls.
198      * @param map a map allowing to give some objects to the adapter.
199      * @param staticMode - Is that generated method is static (client case).
200      */

201     public InjectionClassAdapter(final ClassAnnotationMetadata classAnnotationMetadata, final ClassVisitor cv,
202             final Map JavaDoc<String JavaDoc, Object JavaDoc> map, final boolean staticMode) {
203         super(cv);
204         this.classAnnotationMetadata = classAnnotationMetadata;
205         this.map = map;
206         this.staticMode = staticMode;
207     }
208
209     /**
210      * Visits the end of the class. This method, which is the last one to be
211      * called, is used to inform the visitor that all the fields and methods of
212      * the class have been visited.
213      */

214     @Override JavaDoc
215     public void visitEnd() {
216         super.visitEnd();
217
218         // now, adds the injected method
219
addInjectedMethod();
220
221         // Adds methods if it's not a bean (as it should have been already added by the bean class adapter).
222
// If it's a super class of a bean, as the class that will be instantiated
223
// is the bean's class, the methods won't be used.
224
// It it's an interceptor class, the interceptor manager will call the setters methods
225
if (!classAnnotationMetadata.isBean()) {
226             addDefaultMethods();
227         }
228     }
229
230     /**
231      * Generated methods allowing to set a context and a factory.
232      * This allows to set on injectors the bean's session context and its factory.
233      */

234     private void addDefaultMethods() {
235         // Adds the factory attribute and its getter/setter.
236
CommonClassGenerator.addFieldGettersSetters(cv, classAnnotationMetadata.getClassName(), "easyBeansFactory",
237                 Factory JavaDoc.class);
238
239         // Adds the easyBeansContext attribute and its getter/setter.
240
Class JavaDoc 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     /**
253      * Generates the injectedByEasyBeans() method on the current class.
254      */

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 JavaDoc[] {"org/objectweb/easybeans/api/injection/EasyBeansInjectionException"});
263         mv.visitCode();
264
265         // First, call the super class method (if the super class has been
266
// analyzed) and if there is one
267
String JavaDoc 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                     // generate call to super method : super.INJECTED_METHOD();
274
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 it is a bean, call the interceptorManager and the attributes (like context and factory)
283
if (classAnnotationMetadata.isBean()) {
284             String JavaDoc clNameManager = classAnnotationMetadata.getClassName()
285             + EasyBeansInvocationContextGenerator.SUFFIX_INTERCEPTOR_MANAGER;
286
287             // this.interceptorManager.setEasyBeansContext(easyBeansContext);
288
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             // this.interceptorManager.injectedByEasyBeans();
297
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     /**
312      * Generates the body of the injectedByEasyBeans() method if any.<br> Else,
313      * do nothing.
314      * @param mv the method visitor object used to add some code.
315      */

316     private void generateBodyInjectedMethod(final MethodVisitor mv) {
317
318         // generates injection for annotations on the class itself
319
generateClassInjection(mv);
320
321         // Generates injection for attributes
322
generateAttributesInjection(mv);
323
324         // Generates injection for setters methods
325
generateSettersInjection(mv);
326
327     }
328
329     /**
330      * Generates the calls to populate ENC environment by using annotations on the class itself.
331      * @param mv the method visitor used to inject bytecode.
332      */

333     private void generateClassInjection(final MethodVisitor mv) {
334         // Get annotations on the class
335

336         // &#64;PersistenceContexts annotation
337
List JavaDoc<JavaxPersistenceContext> javaxPersistencePersistenceContexts = classAnnotationMetadata
338                 .getJavaxPersistencePersistenceContexts();
339         if (javaxPersistencePersistenceContexts != null && javaxPersistencePersistenceContexts.size() > 0) {
340             // For each javaxPersistenceContext
341
for (JavaxPersistenceContext javaxPersistenceContext : javaxPersistencePersistenceContexts) {
342                 bindClassPersistenceContext(javaxPersistenceContext, mv);
343             }
344         }
345         // &#64;PersistenceContext annotation
346
if (classAnnotationMetadata.isPersistenceContext()) {
347             bindClassPersistenceContext(classAnnotationMetadata.getJavaxPersistenceContext(), mv);
348         }
349
350         // &#64;PersistenceUnits annotation
351
List JavaDoc<JavaxPersistenceUnit> javaxPersistencePersistenceUnits = classAnnotationMetadata
352                 .getJavaxPersistencePersistenceUnits();
353         if (javaxPersistencePersistenceUnits != null && javaxPersistencePersistenceUnits.size() > 0) {
354             // For each javaxPersistenceUnit
355
for (JavaxPersistenceUnit javaxPersistenceUnit : javaxPersistencePersistenceUnits) {
356                 bindClassPersistenceUnit(javaxPersistenceUnit, mv);
357             }
358         }
359         // &#64;PersistenceUnit annotation
360
if (classAnnotationMetadata.isPersistenceUnit()) {
361             bindClassPersistenceUnit(classAnnotationMetadata.getJavaxPersistenceUnit(), mv);
362         }
363
364         // &#64;EJBs annotation
365
List JavaDoc<JEjbEJB> jEjbs = classAnnotationMetadata.getJEjbEJBs();
366         if (jEjbs != null && jEjbs.size() > 0) {
367             // For each jEJB
368
for (JEjbEJB jEJB : jEjbs) {
369                 bindClassEJB(jEJB, mv);
370             }
371         }
372         // &#64;EJB annotation
373
JEjbEJB jEJB = classAnnotationMetadata.getJEjbEJB();
374         if (jEJB != null) {
375             // For each ejb, do :
376
bindClassEJB(jEJB, mv);
377         }
378
379
380         // &#64;Resources annotation
381
List JavaDoc<JAnnotationResource> jAnnotationResources = classAnnotationMetadata.getJAnnotationResources();
382         if (jAnnotationResources != null && jAnnotationResources.size() > 0) {
383             // For each jAnnotationResource
384
for (JAnnotationResource jAnnotationResource : jAnnotationResources) {
385                 bindResource(jAnnotationResource, mv);
386             }
387         }
388         // &#64;Resource annotation
389
JAnnotationResource jAnnotationResource = classAnnotationMetadata.getJAnnotationResource();
390         if (jAnnotationResource != null) {
391             bindResource(jAnnotationResource, mv);
392         }
393
394
395     }
396
397
398     /**
399      * Generates the calls to methods that will set the attributes value.
400      * @param mv the method visitor used to inject bytecode.
401      */

402     private void generateAttributesInjection(final MethodVisitor mv) {
403
404         for (FieldAnnotationMetadata fieldMetaData : classAnnotationMetadata.getFieldAnnotationMetadataCollection()) {
405
406             // Get type of interface
407
Type typeInterface = Type.getType(fieldMetaData.getJField().getDescriptor());
408             String JavaDoc itfName = typeInterface.getClassName();
409
410             // &#64;PersistenceContext annotation
411
if (fieldMetaData.isPersistenceContext()) {
412                 // validate
413
validateAccessFieldAnnotation(fieldMetaData);
414
415                 // Check that attribute is EntityManager
416
if (!ENTITYMANAGER_ITF.equals(itfName)) {
417                     throw new IllegalStateException JavaDoc(
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                 // add this.em =
427
// EntityManagerHelper.getEntityManager(getEasyBeansContext(),
428
// "myUnitName", PersistenceContextType.EXTENDED);
429
mv.visitVarInsn(ALOAD, 0);
430
431
432                 // call em helper
433
addCallEntityManagerHelper(javaxPersistenceContext, mv);
434
435                 // Set result in the field
436
mv.visitFieldInsn(PUTFIELD, classAnnotationMetadata.getClassName(), fieldMetaData.getFieldName(),
437                         "Ljavax/persistence/EntityManager;");
438
439                 // Bind value in JNDI
440
javaxPersistenceContext.setName(getJndiName(javaxPersistenceContext.getName(), fieldMetaData));
441                 bindClassPersistenceContext(javaxPersistenceContext, mv);
442
443             }
444
445             // &#64;PersistenceUnit annotation
446
if (fieldMetaData.isPersistenceUnit()) {
447                 // validate
448
validateAccessFieldAnnotation(fieldMetaData);
449
450                 // Check that attribute is EntityManager
451
if (!ENTITYMANAGERFACTORY_ITF.equals(itfName)) {
452                     throw new IllegalStateException JavaDoc(
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                 // add this.emf = EntityManagerHelper.getEntityManagerFactory(getEasyBeansContext(), "myUnitName");
462

463                 mv.visitVarInsn(ALOAD, 0);
464                 // get EMF
465
addCallEntityManagerFactoryHelper(javaxPersistenceUnit, mv);
466                 // set attribute
467
mv.visitFieldInsn(PUTFIELD, classAnnotationMetadata.getClassName(), fieldMetaData.getFieldName(),
468                         "Ljavax/persistence/EntityManagerFactory;");
469
470                 // Bind value in JNDI
471
javaxPersistenceUnit.setName(getJndiName(javaxPersistenceUnit.getName(), fieldMetaData));
472                 bindClassPersistenceUnit(javaxPersistenceUnit, mv);
473             }
474
475             // &#64;EJB annotation
476
JEjbEJB jEjb = fieldMetaData.getJEjbEJB();
477             if (jEjb != null) {
478                 // validate
479
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                 // ejbName ?
486
String JavaDoc beanName = jEjb.getBeanName();
487                 String JavaDoc 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             // &#64;Resource annotation
502
JAnnotationResource jAnnotationResource = fieldMetaData.getJAnnotationResource();
503             if (jAnnotationResource != null) {
504                 String JavaDoc mappedName = jAnnotationResource.getMappedName();
505
506                 // validate
507
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                     // this.attribute = getEasyBeansContext();
514
mv.visitVarInsn(ALOAD, 0);
515                     addCallGetEasyBeansContext(mv, "javax/ejb/SessionContext");
516                     mv.visitFieldInsn(PUTFIELD, classAnnotationMetadata.getClassName(), fieldMetaData.getFieldName(),
517                             "Ljavax/ejb/SessionContext;");
518                     // Define the type (if missing)
519
jAnnotationResource.setType(SESSION_CONTEXT);
520
521                     // Set default name if not present.
522
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                     // this.attribute = getEasyBeansContext();
530
mv.visitVarInsn(ALOAD, 0);
531                     addCallGetEasyBeansContext(mv, "javax/ejb/MessageDrivenContext");
532                     mv.visitFieldInsn(PUTFIELD, classAnnotationMetadata.getClassName(), fieldMetaData.getFieldName(),
533                             "Ljavax/ejb/MessageDrivenContext;");
534                     // Define the type (if missing)
535
jAnnotationResource.setType(MESSAGEDRIVEN_CONTEXT);
536
537                     // Set default name if not present.
538
jAnnotationResource.setName(getJndiName(jAnnotationResource.getName(), fieldMetaData));
539
540                     bindResource(jAnnotationResource, mv);
541
542                 } else if (isEnvEntry(typeInterface)) { // Env-Entry
543
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                     //TODO: Change from REGISTRY to JAVA_COMP_ENV
552
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                     // Needs to get timerservice with the bean's context.
560
//this.fieldtimerService = getEasyBeansContext().getTimerService();
561
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                     // this.orb = ORBInitHelper.getORB(); (non static)
569
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     /**
585      * Generates the calls to methods that will call the setters methods.
586      * @param mv the method visitor used to inject bytecode.
587      */

588     private void generateSettersInjection(final MethodVisitor mv) {
589
590         for (MethodAnnotationMetadata methodMetaData : classAnnotationMetadata.getMethodAnnotationMetadataCollection()) {
591             // Ignore inherited methods (managed by super class)
592
if (methodMetaData.isInherited()) {
593                 continue;
594             }
595
596             JAnnotationResource jAnnotationResource = methodMetaData.getJAnnotationResource();
597             // &#64;Resource annotation
598
if (jAnnotationResource != null) {
599                 Type typeInterface = validateSetterMethod(methodMetaData);
600                 String JavaDoc itfName = typeInterface.getClassName();
601
602                 // Env-Entry
603
if (isEnvEntry(typeInterface)) {
604                     callMethodJndiEnv(jAnnotationResource.getName(), typeInterface, mv, methodMetaData,
605                             classAnnotationMetadata.getClassName(), JAVA_COMP_ENV);
606                 } else if (isJNDIResourceInjection(itfName)) {
607                     //TODO: Change from REGISTRY to JAVA_COMP_ENV
608
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                     // add call to : setterMethod(getEasyBeansContext());
615
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                     // Define the type (if missing)
621
jAnnotationResource.setType(SESSION_CONTEXT);
622                     // Set default name if not present.
623
jAnnotationResource.setName(getJndiName(jAnnotationResource.getName(), methodMetaData));
624                     bindResource(jAnnotationResource, mv);
625                 } else if (MESSAGEDRIVEN_CONTEXT.equals(itfName)) {
626                     // add call to : setterMethod(getEasyBeansContext());
627
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                     // Define the type (if missing)
633
jAnnotationResource.setType(MESSAGEDRIVEN_CONTEXT);
634                     // Set default name if not present.
635
jAnnotationResource.setName(getJndiName(jAnnotationResource.getName(), methodMetaData));
636                     bindResource(jAnnotationResource, mv);
637                 }
638             }
639
640             // &#64;EJB annotation
641
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 JavaDoc itfName = typeInterface.getClassName();
648
649                 JNDIResolver jndiResolver = (JNDIResolver) map.get(JNDIResolver.NAME);
650                 // ejbName ?
651
String JavaDoc beanName = jEjb.getBeanName();
652                 String JavaDoc 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                 // get enc name (or the default name) and bind result
659
String JavaDoc encName = getJndiName(jEjb.getName(), methodMetaData);
660                 callBindLookupJndiRef(encName, jndiName, mv);
661             }
662
663             // &#64;PersistenceContext annotation
664
if (methodMetaData.isPersistenceContext()) {
665                 Type typeInterface = validateSetterMethod(methodMetaData);
666                 String JavaDoc itfName = typeInterface.getClassName();
667
668                 // Check that arg of the method is EntityManager
669
if (!ENTITYMANAGER_ITF.equals(itfName)) {
670                     throw new IllegalStateException JavaDoc(
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                 // add
679
// setterName(EntityManagerHelper.getEntityManager(getEasyBeansContext(),
680
// "myUnitName", PersistenceContextType.EXTENDED);
681

682                 mv.visitVarInsn(ALOAD, 0);
683
684                 // call em helper
685
addCallEntityManagerHelper(javaxPersistenceContext, mv);
686
687                 // call setter method
688
mv.visitMethodInsn(INVOKEVIRTUAL, classAnnotationMetadata.getClassName(), methodMetaData
689                         .getMethodName(), "(Ljavax/persistence/EntityManager;)V");
690
691
692                 // bind value in ENC environment
693
javaxPersistenceContext.setName(getJndiName(javaxPersistenceContext.getName(), methodMetaData));
694                 bindClassPersistenceContext(javaxPersistenceContext, mv);
695
696
697             }
698
699             // &#64;PersistenceUnit annotation
700
if (methodMetaData.isPersistenceUnit()) {
701                 Type typeInterface = validateSetterMethod(methodMetaData);
702                 String JavaDoc itfName = typeInterface.getClassName();
703                 // Check that attribute is EntityManager
704
if (!ENTITYMANAGERFACTORY_ITF.equals(itfName)) {
705                     throw new IllegalStateException JavaDoc(
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                 // add
715
// setterName(EntityManagerHelper.getEntityManagerFactory(getEasyBeansContext(),
716
// "myUnitName"));
717

718                 mv.visitVarInsn(ALOAD, 0);
719                 // get EMF
720
addCallEntityManagerFactoryHelper(javaxPersistenceUnit, mv);
721                 // call setter method
722
mv.visitMethodInsn(INVOKEVIRTUAL, classAnnotationMetadata.getClassName(), methodMetaData
723                         .getMethodName(), "(Ljavax/persistence/EntityManagerFactory;)V");
724
725                 // Bind value in JNDI
726
javaxPersistenceUnit.setName(getJndiName(javaxPersistenceUnit.getName(), methodMetaData));
727                 bindClassPersistenceUnit(javaxPersistenceUnit, mv);
728             }
729
730         }
731     }
732
733
734     /**
735      * Ensure that this method is a valid setter method and return ASM type of the first arg of the method.
736      * @param methodMetaData the metadata to check
737      * @return ASM type of the first arg of the method.
738      */

739     private Type validateSetterMethod(final MethodAnnotationMetadata methodMetaData) {
740         // validate access
741
validateAccessMethodAnnotation(methodMetaData);
742
743         JMethod jMethod = methodMetaData.getJMethod();
744         // Should be a setter
745
if (!jMethod.getName().startsWith("set") || jMethod.getName().equalsIgnoreCase("set")) {
746             throw new IllegalStateException JavaDoc("Method '" + jMethod
747                     + "' is invalid. Should be in the setter form setXXX().");
748         }
749
750         // Get type of interface
751
// Get arguments of the method.
752
Type[] args = Type.getArgumentTypes(jMethod.getDescriptor());
753         if (args.length != 1) {
754             throw new IllegalStateException JavaDoc("Method args '" + Arrays.asList(args) + "' for method '" + jMethod
755                     + "' are invalid. Length should be of 1.");
756         }
757         return args[0];
758     }
759
760     /**
761      * Return true if the given type is a type used in env-entry.
762      * @param type an ASM type.
763      * @return true if this entry is used in env-entry.
764      */

765     private boolean isEnvEntry(final Type type) {
766         String JavaDoc itfName = type.getClassName();
767         return String JavaDoc.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     /**
775      * Add a call to getEasyBeansContext() method in the given method visitor.
776      * @param mv the method visitor on which instructions are added
777      * @param castDesc the cast to do.
778      */

779     private void addCallGetEasyBeansContext(final MethodVisitor mv, final String JavaDoc 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     /**
789      * Add a call to EntityManagerHelper class (PersistenceContext) :
790      * EntityManagerHelper.getEntityManager(getEasyBeansContext(),
791      * unitName, type of persistence).
792      * @param javaxPersistenceContext informations on the persistence context
793      * @param mv the method visitor on which instructions are added
794      */

795     private void addCallEntityManagerHelper(final JavaxPersistenceContext javaxPersistenceContext, final MethodVisitor mv) {
796         // get EasyBeansContext
797
addCallGetEasyBeansContext(mv, null);
798
799         // Persistence-unit name
800
mv.visitLdcInsn(javaxPersistenceContext.getUnitName());
801
802         // Transaction Type
803
mv.visitFieldInsn(GETSTATIC, "javax/persistence/PersistenceContextType", javaxPersistenceContext.getType().toString(),
804                 "Ljavax/persistence/PersistenceContextType;");
805         // Call EntityManagerHelper
806
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     /**
817      * Add a call to EntityManagerHelper class (PersistenceUnit):
818      * EntityManagerHelper.getEntityManagerFactory(getEasyBeansContext(), unitName).
819      * @param javaxPersistenceUnit informations on the persistence unit
820      * @param mv the method visitor on which instructions are added
821      */

822     private void addCallEntityManagerFactoryHelper(final JavaxPersistenceUnit javaxPersistenceUnit, final MethodVisitor mv) {
823         // get EasyBeansContext
824
addCallGetEasyBeansContext(mv, null);
825
826         // Persistence-unit name
827
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     /**
837      * Generates a call to JNDILookupHelper class to get the java:comp/env name
838      * requested.
839      * @param jndiName the name to lookup.
840      * @param type the ASM type
841      * @param mv the method visitor to write code.
842      * @param className the name of the generated class.
843      * @param jndiType the type of access (registry, java:comp/env, etc)
844      */

845     private void callJndi(final String JavaDoc jndiName, final Type type, final MethodVisitor mv,
846             final String JavaDoc className, final JndiType jndiType) {
847         if (!staticMode) {
848             mv.visitVarInsn(ALOAD, 0);
849         }
850         mv.visitLdcInsn(jndiName);
851         String JavaDoc 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 JavaDoc("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     /**
871      * Generates a call to JNDILookupHelper class to get the java:comp/env name
872      * requested.
873      * @param jndiName the name to lookup.
874      * @param type the ASM type.
875      * @param mv the method visitor to write code.
876      * @param fieldMetaData the metadata of the attribute.
877      * @param className the name of the generated class.
878      * @param jndiType the type of access (registry, java:comp/env, etc)
879      */

880     private void callAttributeJndi(final String JavaDoc jndiName, final Type type, final MethodVisitor mv,
881             final FieldAnnotationMetadata fieldMetaData, final String JavaDoc 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 JavaDoc formattedJndiName = getJndiName(jndiName, fieldMetaData);
886         callJndi(formattedJndiName, type, mv, className, jndiType);
887         setField(mv, className, fieldMetaData, type);
888     }
889
890     /**
891      * Sets the value of a field.
892      * @param mv the method visitor to use
893      * @param className the class which contains the attribute.
894      * @param fieldMetaData the metadata corresponding to the attribute
895      * @param type the ASM type of the attribute
896      */

897     private void setField(final MethodVisitor mv, final String JavaDoc className,
898             final FieldAnnotationMetadata fieldMetaData, final Type type) {
899         mv.visitFieldInsn(setField(), className, fieldMetaData.getFieldName(), type.getDescriptor());
900     }
901
902     /**
903      * Sets the value of a field.
904      * @param mv the method visitor to use
905      * @param className the class which contains the method.
906      * @param methodMetaData the metadata corresponding to the method *
907      * @param type the ASM type of the method
908      */

909     private void callSetterMethod(final MethodVisitor mv, final String JavaDoc className,
910             final MethodAnnotationMetadata methodMetaData, final Type type) {
911         mv.visitMethodInsn(INVOKEVIRTUAL, className, methodMetaData.getMethodName(), methodMetaData.getJMethod()
912                 .getDescriptor());
913     }
914
915
916     /**
917      * Generates a call to JNDILookupHelper class to get the java:comp/env name
918      * requested.
919      * @param jndiName the name to lookup.
920      * @param type the ASM type.
921      * @param mv the method visitor to write code.
922      * @param methodMetaData the metadata of the method.
923      * @param className the name of the generated class.
924      * @param jndiType the type of access (registry, java:comp/env, etc)
925      */

926     private void callMethodJndiEnv(final String JavaDoc jndiName, final Type type, final MethodVisitor mv,
927             final MethodAnnotationMetadata methodMetaData, final String JavaDoc 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 JavaDoc checkedJndiName = getJndiName(jndiName, methodMetaData);
932         callJndi(checkedJndiName, type, mv, className, jndiType);
933         callSetterMethod(mv, className, methodMetaData, type);
934     }
935
936
937     /**
938      * Ensures that jndiName is valid and return the default value if it is a null value.
939      * @param jndiName to check
940      * @param fieldAnnotationMetadata attribute's metadata
941      * @return jndi name value.
942      */

943     private String JavaDoc getJndiName(final String JavaDoc jndiName, final FieldAnnotationMetadata fieldAnnotationMetadata) {
944         String JavaDoc 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     /**
955      * Ensures that jndiName is valid and return the default value if it is a null value.
956      * @param jndiName to check
957      * @param methodMetaData attribute's metadata
958      * @return jndi name value.
959      */

960     private String JavaDoc getJndiName(final String JavaDoc jndiName, final MethodAnnotationMetadata methodMetaData) {
961         String JavaDoc newJndiName = jndiName;
962         if (jndiName == null || "".equals(jndiName)) {
963             logger.debug("Property name not defined.");
964             StringBuilder JavaDoc propertyBuilder = new StringBuilder JavaDoc(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     /**
977      * Generates a call to JNDIBinderHelper class to bind an object into the
978      * java:comp/env context.
979      * @param encName the name to bind
980      * @param jndiName the name to link to (LinkRef)
981      * @param mv the method visitor to write code.
982      * @param fieldMetaData the metadata of the attribute (that will be bound)
983      */

984     private void callBindAttributeJndi(final String JavaDoc encName, final String JavaDoc jndiName, final MethodVisitor mv,
985             final FieldAnnotationMetadata fieldMetaData) {
986
987
988         // call : JNDIBinderHelper.bindLinkRefEnvJndiName("localName", "jndiName");
989
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     /**
997      * Generates a call to JNDIBinderHelper class to link an object into the
998      * java:comp/env context.
999      * @param encName the name to bind
1000     * @param jndiName the jndi name to use for the link
1001     * @param mv the method visitor to write code.
1002     */

1003    private void callBindLookupJndiRef(final String JavaDoc encName, final String JavaDoc jndiName, final MethodVisitor mv) {
1004        // use a LinkRef between JNDI name and ENC name
1005
// call : JNDIBinderHelper.bindLinkRefEnvJndiName("localName", "jndiName");
1006

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    /**
1018     * Bind a ref for an EJB in ENC environment.
1019     * @param jEJB annotation to analyze
1020     * @param mv the visitor on which write the bytecode.
1021     */

1022    private void bindClassEJB(final JEjbEJB jEJB, final MethodVisitor mv) {
1023
1024        // JNDIBinderHelper.bindEnvJndiName("encName",
1025
// JNDILookupHelper.getEnvJndiName("jndiName"));
1026

1027
1028        // name attribute is mandatory
1029
String JavaDoc encName = jEJB.getName();
1030        if (encName == null || "".equals(encName)) {
1031            throw new IllegalStateException JavaDoc("Error when analyzing @EJB annotation '" + jEJB
1032                    + "' for the class '" + classAnnotationMetadata.getClassName() + "' : No name !");
1033        }
1034
1035        // jndiName
1036
JNDIResolver jndiResolver = (JNDIResolver) map.get(JNDIResolver.NAME);
1037        // ejbName ?
1038
String JavaDoc beanName = jEJB.getBeanName();
1039        String JavaDoc 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 JavaDoc("No JNDI name found when analyzing @EJB annotation '" + jEJB
1048                    + "' for the class '" + classAnnotationMetadata.getClassName() + "'.");
1049        }
1050
1051        // inject code
1052
callBindLookupJndiRef(encName, jndiName, mv);
1053    }
1054
1055    /**
1056     * Bind a ref for a Resource in ENC environment.
1057     * @param jAnnotationResource annotation to analyze
1058     * @param mv the visitor on which write the bytecode.
1059     */

1060    private void bindResource(final JAnnotationResource jAnnotationResource, final MethodVisitor mv) {
1061        if (DATASOURCE_ITF.equals(jAnnotationResource.getType())
1062                || SESSION_CONTEXT.equals(jAnnotationResource.getType())) {
1063            // get name
1064
String JavaDoc encName = jAnnotationResource.getName();
1065            if (encName == null || "".equals(encName)) {
1066                logger.error("No encName for Annotation resource {0}.", jAnnotationResource);
1067                return;
1068            }
1069            String JavaDoc 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                // inject code
1080
callBindLookupJndiRef(encName, jndiName, mv);
1081            }
1082        }
1083    }
1084
1085
1086    /**
1087     * Bind a ref for a PersistenceContext in ENC environment.
1088     * @param javaxPersistenceContext annotation to analyze
1089     * @param mv the visitor on which write the bytecode.
1090     */

1091    private void bindClassPersistenceContext(final JavaxPersistenceContext javaxPersistenceContext, final MethodVisitor mv) {
1092
1093        // Add :
1094
// JNDIBinderHelper.bindEnvJndiName("myName", EntityManagerHelper.getEnt....);
1095

1096        // if name is not valid, do nothing
1097
String JavaDoc 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        // name for ENC
1104
mv.visitLdcInsn(name);
1105
1106        // call em helper
1107
addCallEntityManagerHelper(javaxPersistenceContext, mv);
1108
1109        // bind in ENC
1110
mv.visitMethodInsn(INVOKESTATIC, "org/objectweb/easybeans/injection/JNDIBinderHelper", "bindEnvJndiName",
1111        "(Ljava/lang/String;Ljava/lang/Object;)V");
1112    }
1113
1114
1115    /**
1116     * Bind a ref for a PersistenceUnit in ENC environment.
1117     * @param javaxPersistenceUnit annotation to analyze
1118     * @param mv the visitor on which write the bytecode.
1119     */

1120    private void bindClassPersistenceUnit(final JavaxPersistenceUnit javaxPersistenceUnit, final MethodVisitor mv) {
1121        // Add :
1122
// JNDIBinderHelper.bindEnvJndiName("myName", EntityManagerFactory.getEnt....);
1123

1124        // if name is not valid, do nothing
1125
String JavaDoc 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        // name for ENC
1132
mv.visitLdcInsn(name);
1133
1134        // get EMF
1135
addCallEntityManagerFactoryHelper(javaxPersistenceUnit, mv);
1136
1137        // bind in ENC
1138
mv.visitMethodInsn(INVOKESTATIC, "org/objectweb/easybeans/injection/JNDIBinderHelper", "bindEnvJndiName",
1139        "(Ljava/lang/String;Ljava/lang/Object;)V");
1140    }
1141
1142
1143    /**
1144     * @return the opCode used for non-static or static mode.
1145     */

1146    private int setField() {
1147        int opCode = PUTFIELD;
1148        if (staticMode) {
1149            opCode = PUTSTATIC;
1150        }
1151        return opCode;
1152    }
1153
1154    /**
1155     * Check that the annotation is not used on a final field or static field
1156     * (except client mode).
1157     * @param field the attribute to check.
1158     */

1159    private void validateAccessFieldAnnotation(final FieldAnnotationMetadata field) {
1160        if (accessTest(field.getJField().getAccess(), ACC_FINAL)) {
1161            throw new IllegalStateException JavaDoc("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 JavaDoc("The '" + field
1166                    + "' attribute is a static attribute which is not compliant for dependency injection.");
1167        }
1168    }
1169
1170    /**
1171     * Check that the annotation is not used on a final field or static field
1172     * (except client mode).
1173     * @param methodData the method to check.
1174     */

1175    private void validateAccessMethodAnnotation(final MethodAnnotationMetadata methodData) {
1176        if (!staticMode && accessTest(methodData.getJMethod().getAccess(), ACC_STATIC)) {
1177            throw new IllegalStateException JavaDoc("The '" + methodData
1178                    + "' method is a static attribute which is not compliant for dependency injection.");
1179        }
1180    }
1181
1182
1183    /**
1184     * @param access the full access modified to check
1185     * @param checkedAccess the access to check
1186     * @return true if it is ok, else false.
1187     */

1188    private boolean accessTest(final int access, final int checkedAccess) {
1189        return (access & checkedAccess) == checkedAccess;
1190    }
1191
1192    /**
1193     * If the resource is a JNDI resource injection, return true.<br>
1194     * This is the case of DataSource, JMS Queues/Topics & JMS factories, etc.
1195     * @param itfName the name of the interface to check.
1196     * @return true if it is a JNDI resource injection
1197     */

1198    private boolean isJNDIResourceInjection(final String JavaDoc 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