KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > easybeans > enhancer > interceptors > InterceptorManagerGenerator


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: InterceptorManagerGenerator.java 1121 2006-09-27 08:51:06Z benoitf $
23  * --------------------------------------------------------------------------
24  */

25
26 package org.objectweb.easybeans.enhancer.interceptors;
27
28 import java.util.List JavaDoc;
29
30 import org.objectweb.asm.ClassWriter;
31 import org.objectweb.asm.MethodVisitor;
32 import org.objectweb.asm.Type;
33 import org.objectweb.easybeans.api.Factory;
34 import org.objectweb.easybeans.api.container.EZBEJBContext;
35 import org.objectweb.easybeans.deployment.annotations.metadata.EjbJarAnnotationMetadata;
36 import org.objectweb.easybeans.enhancer.CommonClassGenerator;
37
38 /**
39  * This generates a class that manage the interceptor of a given bean. It
40  * manages the lifecycle of the interceptors and allow to inject resources
41  * (dependency injection).
42  * @author Florent Benoit
43  */

44 public class InterceptorManagerGenerator extends CommonClassGenerator {
45
46     /**
47      * Metadata to retrieve info on interceptors.
48      */

49     private EjbJarAnnotationMetadata ejbJarAnnotationMetadata = null;
50
51     /**
52      * Name of the class to generate.
53      */

54     private String JavaDoc generatedClassName = null;
55
56     /**
57      * List of interceptors classes that are managed.
58      */

59     private List JavaDoc<String JavaDoc> allInterceptors = null;
60
61     /**
62      * Interface of this invocation context.
63      */

64     public static final String JavaDoc[] INTERFACES = new String JavaDoc[] {"org/objectweb/easybeans/api/injection/EasyBeansInjection"};
65
66     /**
67      * EZBEJBContext type descriptor.
68      */

69     private static final String JavaDoc EZB_EJBCONTEXT_DESC = Type.getDescriptor(EZBEJBContext.class);
70
71     /**
72      * Constructor.
73      * @param ejbJarAnnotationMetadata the metadata to search interceptor class metadata.
74      * @param generatedClassName the name of the class to generate.
75      * @param allInterceptors interceptors that needs to be managed.
76      */

77     public InterceptorManagerGenerator(final EjbJarAnnotationMetadata ejbJarAnnotationMetadata,
78             final String JavaDoc generatedClassName, final List JavaDoc<String JavaDoc> allInterceptors) {
79         super(new ClassWriter(true));
80         this.ejbJarAnnotationMetadata = ejbJarAnnotationMetadata;
81         this.generatedClassName = generatedClassName;
82         this.allInterceptors = allInterceptors;
83     }
84
85     /**
86      * Generates the class. It call sub methods for being more clear for read
87      * the code
88      */

89     public void generate() {
90         addClassDeclaration();
91         addAttributes();
92         addConstructor();
93         addMethods();
94         endClass();
95     }
96
97     /**
98      * Creates the declaration of the class with the given interfaces.
99      */

100     private void addClassDeclaration() {
101         // create class
102
getCW().visit(GENERATED_CLASS_VERSION, ACC_PUBLIC + ACC_SUPER, generatedClassName, null, "java/lang/Object",
103                 INTERFACES);
104     }
105
106     /**
107      * Add attributes of the class. Attributes are interceptors names. ie :
108      * private Interceptor interceptor;
109      */

110     private void addAttributes() {
111         for (String JavaDoc interceptor : allInterceptors) {
112             String JavaDoc fieldName = getField(interceptor);
113             addAttribute(ACC_PRIVATE, fieldName, encodeClassDesc(interceptor));
114         }
115     }
116
117     /**
118      * Gets the field name for a given interceptor.
119      * @param interceptorClass the given interceptor.
120      * @return a field name.
121      */

122     private static String JavaDoc getField(final String JavaDoc interceptorClass) {
123         return interceptorClass.replace("/", "");
124     }
125
126     /**
127      * Gets the getter method name for a given interceptor.
128      * @param interceptorClass the given interceptor.
129      * @return a getter method name.
130      */

131     private static String JavaDoc getMethod(final String JavaDoc interceptorClass) {
132         return "get" + interceptorClass.replace("/", "");
133     }
134
135     /**
136      * Creates the constructor which should look like.
137      *
138      * <pre>
139      * public XXXInterceptorManager() {
140      * this.interceptor = new Interceptor();
141      * this.interceptor2 = new Interceptor2();
142      * }
143      * </pre>
144      */

145     private void addConstructor() {
146         // Generate constructor
147
MethodVisitor mv = getCW().visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
148         mv.visitCode();
149
150         // Call super constructor
151
mv.visitVarInsn(ALOAD, 0);
152         mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
153
154         // Build instance of interceptors
155
for (String JavaDoc interceptor : allInterceptors) {
156             mv.visitVarInsn(ALOAD, 0);
157             mv.visitTypeInsn(NEW, interceptor);
158             mv.visitInsn(DUP);
159             mv.visitMethodInsn(INVOKESPECIAL, interceptor, "<init>", "()V");
160             mv.visitFieldInsn(PUTFIELD, generatedClassName, getField(interceptor), encodeClassDesc(interceptor));
161         }
162
163         // need to add return instruction
164
mv.visitInsn(RETURN);
165
166         // visit max compute automatically
167
mv.visitMaxs(0, 0);
168         mv.visitEnd();
169     }
170
171     /**
172      * Add methods of the class.
173      */

174     private void addMethods() {
175         addGetterMethods();
176         addInjectedMethod();
177         addDefaultMethods();
178     }
179
180     /**
181      * Generated methods allowing to set a context and a factory. This allows to
182      * set on injectors the bean's session context and its factory.
183      */

184     private void addDefaultMethods() {
185         // Adds the factory attribute and its getter/setter.
186
CommonClassGenerator.addFieldGettersSetters(getCW(), generatedClassName, "easyBeansFactory", Factory.class);
187
188         // Adds the sessionContext attribute and its getter/setter.
189
CommonClassGenerator.addFieldGettersSetters(getCW(), generatedClassName, "easyBeansContext",
190                 EZBEJBContext.class);
191     }
192
193
194     /**
195      * Generates a getter method for each interceptor. ie :
196      *
197      * <pre>
198      * public Interceptor getInterceptor() {
199      * return interceptor;
200      * }
201      * </pre>
202      */

203     private void addGetterMethods() {
204         for (String JavaDoc interceptor : allInterceptors) {
205             MethodVisitor mv = getCW().visitMethod(ACC_PUBLIC, getMethod(interceptor),
206                     "()" + encodeClassDesc(interceptor), null, null);
207             mv.visitCode();
208             mv.visitVarInsn(ALOAD, 0);
209             mv.visitFieldInsn(GETFIELD, generatedClassName, getField(interceptor), encodeClassDesc(interceptor));
210             mv.visitInsn(ARETURN);
211             mv.visitMaxs(0, 0);
212             mv.visitEnd();
213         }
214     }
215
216     /**
217      * For each interceptor, call injectedByEasyBeans on it (only if these
218      * interceptors have been analyzed).
219      *
220      * <pre>
221      * public void injectedByEasyBeans() {
222      * interceptorXX.setEasyBeansContext(easyBeansContext);
223      * interceptorXX.injectedByEasyBeans();
224      * interceptorXX.injectedByEasyBeans();
225      * }
226      * </pre>
227      */

228     private void addInjectedMethod() {
229         MethodVisitor mv = getCW().visitMethod(ACC_PUBLIC, "injectedByEasyBeans", "()V", null, null);
230         mv.visitCode();
231
232         for (String JavaDoc interceptor : allInterceptors) {
233             // if interceptor has been analyzed, call injectedByEasyBeans method
234
// Set also the bean's context and its factory.
235
if (ejbJarAnnotationMetadata.getClassAnnotationMetadata(interceptor) != null) {
236                 String JavaDoc fieldName = getField(interceptor);
237
238                 // interceptor.setEasyBeansContext(easyBeansContext);
239
mv.visitVarInsn(ALOAD, 0);
240                 mv.visitFieldInsn(GETFIELD, generatedClassName, fieldName, encodeClassDesc(interceptor));
241                 mv.visitVarInsn(ALOAD, 0);
242                 mv.visitFieldInsn(GETFIELD, generatedClassName, "easyBeansContext",
243                         EZB_EJBCONTEXT_DESC);
244                 mv.visitMethodInsn(INVOKEVIRTUAL, interceptor, "setEasyBeansContext",
245                         "(" + EZB_EJBCONTEXT_DESC + ")V");
246
247                 // interceptorXX.injectedByEasyBeans();
248
mv.visitVarInsn(ALOAD, 0);
249                 mv.visitFieldInsn(GETFIELD, generatedClassName, fieldName, encodeClassDesc(interceptor));
250                 mv.visitMethodInsn(INVOKEVIRTUAL, interceptor, "injectedByEasyBeans", "()V");
251             }
252         }
253         mv.visitInsn(RETURN);
254         mv.visitMaxs(0, 0);
255         mv.visitEnd();
256     }
257
258     /**
259      * Called when the generated class is done.
260      */

261     private void endClass() {
262         getCW().visitEnd();
263     }
264
265     /**
266      * @return the bytecode of the generated class.
267      */

268     public byte[] getBytes() {
269         return getCW().toByteArray();
270     }
271
272 }
273
Popular Tags