KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > ejb > codegen > WrapperGenerator


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23 package com.sun.ejb.codegen;
24
25 import java.lang.reflect.*;
26 import java.io.*;
27 import java.util.*;
28 import java.util.logging.*;
29 import com.sun.logging.*;
30
31 import sun.rmi.rmic.IndentingWriter;
32
33 import javax.ejb.EnterpriseBean JavaDoc;
34 import javax.ejb.SessionBean JavaDoc;
35 import javax.ejb.EntityBean JavaDoc;
36 import com.sun.enterprise.deployment.*;
37 import com.sun.enterprise.util.JarClassLoader;
38 import com.sun.enterprise.util.LocalStringManagerImpl;
39
40 /**
41  * This class is used to generate the type specific EJBObject implementation
42  */

43
44 public class WrapperGenerator extends Generator {
45
46     private static LocalStringManagerImpl localStrings =
47     new LocalStringManagerImpl(WrapperGenerator.class);
48     private static Logger _logger=null;
49     static{
50        _logger=LogDomains.getLogger(LogDomains.DPL_LOGGER);
51     }
52
53     public static final String JavaDoc REMOTE_SUFFIX = "_EJBObjectImpl";
54     public static final String JavaDoc LOCAL_SUFFIX = "_EJBLocalObjectImpl";
55
56     private Class JavaDoc bean;
57     private Class JavaDoc componentInterface; // remote or local interface
58
private Method[] bizMethods;
59     private String JavaDoc wrapperBase;
60     private String JavaDoc wrapperImpl;
61     private EjbDescriptor dd;
62     private boolean isLocal;
63
64     /**
65      * Get the fully qualified name of the generated class.
66      * Note: the remote/local implementation class is in the same package
67      * as the bean class, NOT the remote/local interface.
68      * @return the name of the generated class.
69      */

70     public String JavaDoc getGeneratedClass() {
71     String JavaDoc pname = getPackageName(bean.getName());
72     if(pname != null)
73         return pname+"."+wrapperImpl;
74     else
75         return wrapperImpl;
76     }
77     
78     public static String JavaDoc getDefaultEJBObjectImplClassName(EjbDescriptor desc) {
79     //IASRI 4725194 return desc.getEjbClassName() + REMOTE_SUFFIX;
80
return desc.getEjbImplClassName() + REMOTE_SUFFIX;
81     }
82     
83     /**
84      * Construct the Wrapper generator with the specified deployment
85      * descriptor and class loader.
86      * @param the Deployment Descriptor
87      * @param the class loader.
88      * @exception GeneratorException.
89      */

90     public WrapperGenerator(DeploymentContext context, EjbDescriptor dd,
91                 boolean isLocal, Vector existingClassNames)
92     throws GeneratorException
93     {
94     super();
95
96     this.dd = dd;
97     this.isLocal = isLocal;
98         
99         ClassLoader JavaDoc cl = context.getClassLoader();
100     try {
101         //IASRI 4725194 this.bean = cl.loadClass(dd.getEjbClassName());
102
this.bean = cl.loadClass(dd.getEjbImplClassName());
103     } catch (ClassNotFoundException JavaDoc ex) {
104         throw new InvalidBean(
105         localStrings.getLocalString(
106         "generator.bean_class_not_found",
107         "Bean class not found "));
108     }
109
110     String JavaDoc compIntfName;
111     if ( isLocal ) {
112         compIntfName = dd.getLocalClassName();
113         ejbClassSymbol = MethodDescriptor.EJB_LOCAL;
114     }
115     else {
116         compIntfName = dd.getRemoteClassName();
117         ejbClassSymbol = MethodDescriptor.EJB_REMOTE;
118     }
119     try {
120         this.componentInterface = cl.loadClass(compIntfName);
121     } catch (ClassNotFoundException JavaDoc ex) {
122         throw new InvalidBean(
123         localStrings.getLocalString(
124         "generator.remote_interface_not_found",
125         "Remote interface not found "));
126     }
127     
128     String JavaDoc suffix;
129     if ( isLocal ) {
130         wrapperBase = "com.sun.ejb.containers.EJBLocalObjectImpl";
131         suffix = LOCAL_SUFFIX;
132     }
133     else {
134         wrapperBase = "com.sun.ejb.containers.EJBObjectImpl";
135         suffix = REMOTE_SUFFIX;
136     }
137
138     // find a unique classname for this ejbObject/LocalObject impl
139
String JavaDoc wrapperClassName = getUniqueClassName(context, bean.getName(),
140                           suffix, existingClassNames);
141     wrapperImpl = getBaseName(wrapperClassName);
142
143     bizMethods = removeDups(componentInterface.getMethods());
144     bizMethods = removeEJBObjectMethods(bizMethods);
145     }
146
147     private Method[] removeEJBObjectMethods(Method[] methods)
148     {
149         // each remote method
150
ArrayList newArray = new ArrayList();
151         for(int i = 0; i < methods.length; i++) {
152         if( !isEJBObjectMethod(methods[i]) )
153                 newArray.add(methods[i]);
154         }
155         Method[] newMethods = new Method[newArray.size()];
156         return (Method[])newArray.toArray(newMethods);
157     }
158
159
160     /**
161      * Return true is method is on javax.ejb.EJBObject/EJBLocalObject
162      */

163     private boolean isEJBObjectMethod(Method methodToCheck) {
164         Class JavaDoc ejbObjectClz = isLocal ?
165             javax.ejb.EJBLocalObject JavaDoc.class : javax.ejb.EJBObject JavaDoc.class;
166
167         return isEJBIntfMethod(ejbObjectClz, methodToCheck);
168     }
169             
170     /**
171      * Generate the code to the specified output stream.
172      * @param the output stream
173      * @exception GeneratorException on a generation error
174      * @exception IOException on an IO error
175      */

176     public void generate(OutputStream out)
177     throws GeneratorException, IOException
178     {
179     IndentingWriter p = new IndentingWriter(new OutputStreamWriter(out));
180
181     String JavaDoc packageName = getPackageName(bean.getName());
182     if (packageName != null)
183         p.pln("package " + packageName + ";");
184
185     p.plnI("public final class " + wrapperImpl + " extends " +
186         wrapperBase + " implements " + componentInterface.getName() +
187         " {");
188
189     // print static variables for Method objects and static initializer
190
String JavaDoc[] methodVariables = printStaticMethodInit(p, componentInterface,
191                              bizMethods);
192
193     // this is the constructor
194
p.plnI("public " + wrapperImpl + "() "
195         + (isLocal ? "" : "throws java.rmi.RemoteException ") + "{");
196     p.pOln("}");
197
198     // each remote method
199
for(int i = 0; i < bizMethods.length; i++) {
200         printMethodImpl(p, bizMethods[i], methodVariables[i]);
201     }
202
203     p.pOln("}");
204     p.close();
205     }
206
207
208     /**
209      * Generate the code for a single method.
210      * @param the writer.
211      * @param the method to generate code for.
212      * @exception IOException.
213      */

214     private void printMethodImpl(IndentingWriter p, Method m, String JavaDoc methodVar)
215     throws IOException
216     {
217     p.pln("");
218
219     // print method signature and exceptions
220
p.p("public " + printType(m.getReturnType()) + " "
221         + m.getName() + "(");
222     Class JavaDoc[] params = m.getParameterTypes();
223     for(int i = 0; i < params.length; i++) {
224         if (i != 0)
225         p.p(", ");
226         p.p(printType(params[i]) + " param" + i);
227     }
228     p.p(") ");
229     Class JavaDoc[] exceptions = m.getExceptionTypes();
230     for(int i = 0; i < exceptions.length; i++) {
231         if (i == 0)
232         p.p("throws ");
233         else
234         p.p(", ");
235         p.p(exceptions[i].getName());
236     }
237     p.plnI("{");
238
239     p.pln("com.sun.ejb.Invocation i = new com.sun.ejb.Invocation();");
240     if ( isLocal ) {
241         p.pln("i.isLocal = true;");
242         // Set tx/security attrs only for local invocations.
243
// For remote invocations the generator does not
244
// run unless the interface itself has been modified,
245
// so the attr set in generated code could be wrong for
246
// remote intfs if only deployment desc was modified.
247
p.pln("i.transactionAttribute = com.sun.ejb.Container." +
248                         getTxAttribute(dd, m) + ";");
249         p.pln("i.securityPermissions = com.sun.ejb.Container." +
250                      getSecurityAttribute(dd, m) + ";");
251     }
252     p.pln("i.ejbObject = this;");
253
254     // print code for setting Method object in Invocation
255
p.pln("i.method = " + methodVar + ";");
256
257     if(!m.getReturnType().isPrimitive())
258         p.pln(printType(m.getReturnType()) + " $retVal = null;");
259     else if (m.getReturnType() != void.class) {
260         if(m.getReturnType() == boolean.class)
261             p.pln(printType(m.getReturnType()) + " $retVal = false;");
262         else
263             p.pln(printType(m.getReturnType()) + " $retVal = 0;");
264     }
265
266     // print code for calling biz method on bean class
267
p.pln("try {");
268     p.pln("\tObject[] objarr = new Object["+params.length+"];");
269     p.p("\n");
270     for(int i = 0; i < params.length; i++) {
271         p.p("objarr["+i+"] = ");
272         Class JavaDoc clazz = params[i];
273         p.p(marshallPrimitiveToObject(clazz, i));
274     }
275     p.pln("\t\ti.methodParams = objarr;\n");
276     p.pln("\tthis.getContainer().preInvoke(i);");
277     p.pln("\tClass ejbClass = i.ejb.getClass();");
278     p.pln("\tjava.lang.reflect.Method beanMethod = ejbClass.getMethod(i.method.getName(), i.method.getParameterTypes());");
279     
280     p.pln("\tObject obj = com.sun.enterprise.security.SecurityUtil.runMethod(beanMethod, i, i.ejb , objarr, this.getContainer());");
281     Class JavaDoc clazz = m.getReturnType();
282     p.p(marshallObjectToPrimitive(clazz, "obj", "$retVal"));
283     p.p("\n");
284     
285     p.pln("} catch(Throwable c) {");
286     p.pln("\ti.exception = c;");
287     p.pln("} finally {");
288     p.pln("\tthis.getContainer().postInvoke(i);");
289     p.pln("}");
290
291     // exception handling code
292
p.plnI("if (i.exception != null) {");
293     p.pln("if(i.exception instanceof java.lang.RuntimeException) {");
294     p.pln("\tthrow (java.lang.RuntimeException)i.exception; ");
295     p.p("} ");
296     if ( !isLocal ) {
297         p.pln("else if(i.exception instanceof java.rmi.RemoteException) {");
298         p.pln("\tthrow (java.rmi.RemoteException)i.exception; ");
299         p.p("} ");
300     }
301     for(int i = 0; i < exceptions.length; i++) {
302         if(!exceptions[i].getName().equals("java.rmi.RemoteException")) {
303             p.pln("else if(i.exception instanceof " +
304             exceptions[i].getName() + ") {" );
305             p.pln("\tthrow (" + exceptions[i].getName() + ")i.exception;");
306             p.p("} ");
307         }
308     }
309     if ( isLocal ) {
310         p.pln("else if (i.exception instanceof Exception) {");
311         p.pln("\tthrow new javax.ejb.EJBException(\"Unknown exception\", (Exception)i.exception);");
312         p.pln("}");
313         p.pln("else {");
314         p.pln("\tthrow new javax.ejb.EJBException(i.exception.getMessage());");
315         p.pln("}");
316     }
317     else {
318         p.pln("else {");
319         p.pln("\tthrow new java.rmi.RemoteException(\"Unknown exception\", i.exception);");
320         p.pln("}");
321     }
322     p.pOln("}");
323         
324
325     // print return code
326
if (m.getReturnType() != void.class)
327         p.pln("return $retVal;");
328     p.pOln("}");
329     }
330     private String JavaDoc marshallPrimitiveToObject(Class JavaDoc clazz , int i){
331     if(clazz.isPrimitive()){
332         if(clazz == int.class){
333         return " new java.lang.Integer(param"+i+");\n";
334         }else if(clazz == boolean.class){
335         return " java.lang.Boolean.valueOf(param"+i+");\n";
336         }else if(clazz == byte.class){
337         return " new java.lang.Byte(param"+i+");\n";
338         }else if(clazz == short.class){
339         return " new java.lang.Short(param"+i+");\n";
340         }else if(clazz == long.class){
341         return " new java.lang.Long(param"+i+");\n";
342         }else if(clazz == float.class){
343         return " new java.lang.Float(param"+i+");\n";
344         }else if(clazz == double.class){
345         return " new java.lang.Double(param"+i+");\n";
346         }else if(clazz == char.class){
347         return " new java.lang.Character(param"+i+");\n";
348         }
349     }
350     return "(java.lang.Object)param"+i+";\n";
351     }
352     private String JavaDoc marshallObjectToPrimitive(Class JavaDoc clazz , String JavaDoc obj, String JavaDoc retVal){
353     if(clazz.isPrimitive()){
354         if(clazz == int.class){
355         return retVal+ "= ((java.lang.Integer)"+ obj+").intValue();\n";
356         }else if(clazz == boolean.class){
357         return retVal+" = ((java.lang.Boolean)"+obj+").booleanValue();\n";
358         }else if(clazz == byte.class){
359         return retVal+" = ((java.lang.Byte)"+obj+").byteValue();\n";
360         }else if(clazz == short.class){
361         return retVal+" = ((java.lang.Short)"+obj+").shortValue();\n";
362         }else if(clazz == long.class){
363         return retVal+" = ((java.lang.Long)"+obj+").longValue();\n";
364         }else if(clazz == float.class){
365         return retVal+" = ((java.lang.Float)"+obj+").floatValue();\n";
366         }else if(clazz == double.class){
367         return retVal+" = ((java.lang.Double)"+obj+").doubleValue();\n";
368         }else if(clazz == char.class){
369         return retVal+" = ((java.lang.Character)"+obj+").charValue();\n";
370         }else if(clazz == void.class){
371         return "\n";
372         }
373     }
374     return retVal +"= ("+printType(clazz)+") "+obj+";\n";
375     }
376 }
377
Popular Tags