KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > easybeans > enhancer > bean > BeanClassAdapter


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: BeanClassAdapter.java 1133 2006-10-04 14:30:41Z benoitf $
23  * --------------------------------------------------------------------------
24  */

25
26 package org.objectweb.easybeans.enhancer.bean;
27
28 import org.objectweb.asm.ClassAdapter;
29 import org.objectweb.asm.ClassVisitor;
30 import org.objectweb.asm.MethodAdapter;
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 import org.objectweb.easybeans.api.bean.EasyBeansBean;
36 import org.objectweb.easybeans.api.bean.EasyBeansMDB;
37 import org.objectweb.easybeans.api.bean.EasyBeansSFSB;
38 import org.objectweb.easybeans.api.bean.EasyBeansSLSB;
39 import org.objectweb.easybeans.api.container.EZBEJBContext;
40 import org.objectweb.easybeans.deployment.annotations.metadata.ClassAnnotationMetadata;
41 import org.objectweb.easybeans.enhancer.CommonClassGenerator;
42 import org.objectweb.easybeans.enhancer.interceptors.EasyBeansInvocationContextGenerator;
43
44 /**
45  * This class adds a bean interface to the parsed object.<br>
46  * It also adds getEasyBeansFactory method defined in the EasyBeansBean interface.<br>
47  * Stateless bean will have EasyBeansStatelessSessionBean interface, etc.
48  * @author Florent Benoit
49  */

50 public class BeanClassAdapter extends ClassAdapter implements Opcodes {
51
52     /**
53      * Metadata available by this adapter for a class.
54      */

55     private ClassAnnotationMetadata classAnnotationMetadata = null;
56
57     /**
58      * Constructor.
59      * @param classAnnotationMetadata object containing all attributes of the
60      * class
61      * @param cv the class visitor to which this adapter must delegate calls.
62      */

63     public BeanClassAdapter(final ClassAnnotationMetadata classAnnotationMetadata, final ClassVisitor cv) {
64         super(cv);
65         this.classAnnotationMetadata = classAnnotationMetadata;
66     }
67
68     /**
69      * Visits the header of the class.
70      * @param version the class version.
71      * @param access the class's access flags (see
72      * {@link org.objectweb.asm.Opcodes}). This parameter also indicates
73      * if the class is deprecated.
74      * @param name the internal name of the class (see
75      * {@link org.objectweb.asm.Type#getInternalName() getInternalName}).
76      * @param signature the signature of this class. May be <tt>null</tt> if
77      * the class is not a generic one, and does not extend or implement
78      * generic classes or interfaces.
79      * @param superName the internal of name of the super class (see
80      * {@link org.objectweb.asm.Type#getInternalName() getInternalName}).
81      * For interfaces, the super class is {@link Object}. May be
82      * <tt>null</tt>, but only for the {@link Object} class.
83      * @param interfaces the internal names of the class's interfaces (see
84      * {@link org.objectweb.asm.Type#getInternalName() getInternalName}).
85      * May be <tt>null</tt>.
86      */

87     @Override JavaDoc
88     public void visit(final int version, final int access, final String JavaDoc name, final String JavaDoc signature,
89             final String JavaDoc superName, final String JavaDoc[] interfaces) {
90
91         String JavaDoc[] newInterfaces = null;
92
93         // Add new interface with bean
94
if (classAnnotationMetadata.isBean()) {
95             // copy old interfaces in the new array
96
newInterfaces = new String JavaDoc[interfaces.length + 1];
97             System.arraycopy(interfaces, 0, newInterfaces, 0, interfaces.length);
98
99             int indexElement = newInterfaces.length - 1;
100
101             // Add the right interface (SLSB, SFSB, MDB)
102
if (classAnnotationMetadata.isStateless()) {
103                 newInterfaces[indexElement] = Type.getInternalName(EasyBeansSLSB.class);
104             } else if (classAnnotationMetadata.isStateful()) {
105                 newInterfaces[indexElement] = Type.getInternalName(EasyBeansSFSB.class);
106             } else if (classAnnotationMetadata.isMdb()) {
107                 newInterfaces[indexElement] = Type.getInternalName(EasyBeansMDB.class);
108             } else {
109                 newInterfaces[indexElement] = Type.getInternalName(EasyBeansBean.class);
110             }
111         } else {
112             newInterfaces = interfaces;
113         }
114
115         super.visit(version, access, name, signature, superName, newInterfaces);
116
117     }
118     /**
119      * Visits a method of the class. This method <i>must</i> return a new
120      * {@link MethodVisitor} instance (or <tt>null</tt>) each time it is
121      * called, i.e., it should not return a previously returned visitor.
122      *
123      * @param access the method's access flags (see {@link Opcodes}). This
124      * parameter also indicates if the method is synthetic and/or
125      * deprecated.
126      * @param name the method's name.
127      * @param desc the method's descriptor (see {@link Type Type}).
128      * @param signature the method's signature. May be <tt>null</tt> if the
129      * method parameters, return type and exceptions do not use generic
130      * types.
131      * @param exceptions the internal names of the method's exception classes
132      * (see {@link Type#getInternalName() getInternalName}). May be
133      * <tt>null</tt>.
134      * @return an object to visit the byte code of the method, or <tt>null</tt>
135      * if this class visitor is not interested in visiting the code of
136      * this method.
137      */

138     @Override JavaDoc
139     public MethodVisitor visitMethod(final int access, final String JavaDoc name, final String JavaDoc desc, final String JavaDoc signature,
140             final String JavaDoc[] exceptions) {
141
142         // if default constructor, then needs to add a call to create a new InterceptorManager
143
if ("<init>".equals(name) && "()V".equals(desc)) {
144             MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
145             return new AddMethodConstructorAdapter(mv);
146         }
147         return super.visitMethod(access, name, desc, signature, exceptions);
148
149     }
150
151
152     /**
153      * Visits the end of the class. This method, which is the last one to be
154      * called, is used to inform the visitor that all the fields and methods of
155      * the class have been visited.
156      */

157     @Override JavaDoc
158     public void visitEnd() {
159         super.visitEnd();
160
161         // Adds the factory attribute and its getter/setter.
162
CommonClassGenerator.addFieldGettersSetters(cv, classAnnotationMetadata.getClassName(),
163                 "easyBeansFactory", Factory.class);
164
165
166         if (classAnnotationMetadata.isBean()) {
167             // Adds interceptor manager
168
CommonClassGenerator.addFieldGettersSetters(cv, classAnnotationMetadata.getClassName(),
169                     "easyBeansInterceptorManager", "L" + classAnnotationMetadata.getClassName()
170                             + EasyBeansInvocationContextGenerator.SUFFIX_INTERCEPTOR_MANAGER + ";");
171
172
173             // Adds the context attribute and its getter/setter.
174
CommonClassGenerator.addFieldGettersSetters(cv, classAnnotationMetadata.getClassName(),
175                     "easyBeansContext", EZBEJBContext.class);
176
177             // Add the removed attribute (if bean has been removed)
178
if (classAnnotationMetadata.isSession()) {
179                 CommonClassGenerator.addFieldGettersSetters(cv, classAnnotationMetadata.getClassName(),
180                         "easyBeansRemoved", Boolean.TYPE);
181             }
182
183             // Add id field for stateful
184
if (classAnnotationMetadata.isStateful()) {
185                 CommonClassGenerator.addFieldGettersSetters(cv, classAnnotationMetadata.getClassName(),
186                         "easyBeansStatefulID", Long JavaDoc.class);
187             }
188
189         }
190
191     }
192
193     /**
194      * Adds an entry in the constructor of the bean.
195      * It will initialize the interceptorManager.
196      * @author Florent Benoit
197      */

198     public class AddMethodConstructorAdapter extends MethodAdapter {
199
200         /**
201          * Constructs a new AddMethodConstructorAdapter object.
202          * @param mv the code visitor to which this adapter must delegate calls.
203          */

204         public AddMethodConstructorAdapter(final MethodVisitor mv) {
205             super(mv);
206         }
207
208         /**
209          * Adds instruction just after the start of the method code.
210          * TODO: Analyze when call to super() constructor is done and add instruction after.
211          */

212         @Override JavaDoc
213         public void visitCode() {
214             super.visitCode();
215             String JavaDoc clManager = classAnnotationMetadata.getClassName()
216             + EasyBeansInvocationContextGenerator.SUFFIX_INTERCEPTOR_MANAGER;
217             mv.visitVarInsn(ALOAD, 0);
218             mv.visitTypeInsn(NEW, clManager);
219             mv.visitInsn(DUP);
220             mv.visitMethodInsn(INVOKESPECIAL, clManager, "<init>", "()V");
221             mv.visitFieldInsn(PUTFIELD, classAnnotationMetadata.getClassName(), "easyBeansInterceptorManager", "L"
222                     + clManager + ";");
223
224         }
225
226     }
227
228 }
229
230
Popular Tags