KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > ejb > gen > JVMStubGenerator


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Scott Ferguson
27  */

28
29 package com.caucho.ejb.gen;
30
31 import com.caucho.java.AbstractGenerator;
32 import com.caucho.util.IntMap;
33 import com.caucho.util.L10N;
34 import com.caucho.vfs.IOExceptionWrapper;
35
36 import javax.ejb.EJBHome JavaDoc;
37 import javax.ejb.EJBLocalHome JavaDoc;
38 import javax.ejb.EJBLocalObject JavaDoc;
39 import javax.ejb.EJBObject JavaDoc;
40 import java.io.IOException JavaDoc;
41 import java.lang.reflect.Method JavaDoc;
42 import java.util.ArrayList JavaDoc;
43
44 /**
45  * Generator for stubs.
46  */

47 abstract class JVMStubGenerator extends AbstractGenerator {
48   protected static final L10N L = new L10N(JVMStubGenerator.class);
49   
50   // Classes which can be safely passed by reference because they're
51
// immutable and part of the JDK
52
static IntMap _immutableClasses;
53
54   protected boolean _isProxy = false;
55   protected ArrayList JavaDoc<Method JavaDoc> _proxyMethods = new ArrayList JavaDoc<Method JavaDoc>();
56   protected Class JavaDoc _remoteClass;
57
58   void setProxy(boolean isProxy)
59   {
60     _isProxy = isProxy;
61   }
62
63   /**
64    * Prints the header for a HomeStub
65    */

66   abstract protected void printHeader()
67     throws IOException JavaDoc;
68
69   /**
70    * Prints a direct call for use in the same JVM.
71    *
72    * @param method the method to generate
73    */

74   protected void printMethod(String JavaDoc name, Method JavaDoc method)
75     throws IOException JavaDoc
76   {
77     Class JavaDoc ret = method.getReturnType();
78     Class JavaDoc []params = method.getParameterTypes();
79     
80     printMethodHeader(name, method);
81     
82     boolean needsSerialization = printMethodHead(params, ret);
83
84     printCall(method.getName(), params, ret);
85     
86     printMethodFooter(ret, needsSerialization);
87   }
88
89   protected boolean printMethodHead(Class JavaDoc []params, Class JavaDoc ret)
90     throws IOException JavaDoc
91   {
92     println("{");
93     pushDepth();
94     println("Thread thread = Thread.currentThread();");
95     println("ClassLoader oldLoader = thread.getContextClassLoader();");
96
97     boolean needsSerialization = false;
98     for (int i = 0; i < params.length; i++) {
99       if (needsSerialization(params[i])) {
100         if (! needsSerialization) {
101           println("com.caucho.ejb.protocol.SelfSerializer ser;");
102           println("ser = com.caucho.ejb.protocol.SelfSerializer.allocate();");
103         }
104         println("ser.write(a" + i + ");");
105         needsSerialization = true;
106       }
107     }
108
109     if (needsSerialization(ret) && ! needsSerialization) {
110       println("com.caucho.ejb.protocol.SelfSerializer ser;");
111       println("ser = com.caucho.ejb.protocol.SelfSerializer.allocate();");
112       needsSerialization = true;
113     }
114
115     if (! ret.getName().equals("void")) {
116       printClass(ret);
117       println(" _ret;");
118     }
119
120     println();
121     if (! _isProxy) {
122       println(_remoteClass.getName() + " obj;");
123       println("obj = (" + _remoteClass.getName() + ") _caucho_getObject();");
124     }
125     else {
126       println("Object obj = _caucho_getObject();");
127     }
128     println("thread.setContextClassLoader(_caucho_getClassLoader());");
129     println("try {");
130     pushDepth();
131
132     return needsSerialization;
133   }
134
135   protected void printMethodFooter(Class JavaDoc ret, boolean needsSerialization)
136     throws IOException JavaDoc
137   {
138     if (needsSerialization(ret)) {
139       if (needsSerialization)
140         println("ser.clear();");
141       needsSerialization = true;
142       println("ser.write(_ret);");
143       println("thread.setContextClassLoader(oldLoader);");
144       print("_ret = (");
145       printClass(ret);
146       println(") ser.read();");
147     }
148
149     popDepth();
150     println("} finally {");
151     pushDepth();
152     println("thread.setContextClassLoader(oldLoader);");
153     
154     if (needsSerialization)
155       println("ser.close();");
156
157     popDepth();
158     println("}");
159
160     if (! ret.getName().equals("void"))
161       println("return _ret;");
162     
163     popDepth();
164     println("}");
165   }
166
167   void printCall(String JavaDoc name, Class JavaDoc []params, Class JavaDoc retType)
168     throws IOException JavaDoc
169   {
170     if (_isProxy) {
171       printProxyCall(name, params, retType);
172       return;
173     }
174
175     if (! retType.equals(void.class))
176       print("_ret = ");
177     
178     print("obj." + name + "(");
179     for (int i = 0; i < params.length; i++) {
180       if (i != 0)
181         print(", ");
182       if (needsSerialization(params[i])) {
183         print("(");
184         printClass(params[i]);
185         print(") ser.read()");
186       }
187       else
188         print("a" + i);
189     }
190     println(");");
191   }
192
193   void printProxyCall(String JavaDoc name, Class JavaDoc []params, Class JavaDoc retType)
194     throws IOException JavaDoc
195   {
196     Method JavaDoc method;
197
198     try {
199       method = _remoteClass.getMethod(name, params);
200     } catch (NoSuchMethodException JavaDoc e) {
201       throw new IOExceptionWrapper(e);
202     }
203     _proxyMethods.add(method);
204
205     if (_isProxy) {
206       println("try {");
207       pushDepth();
208     }
209     
210     int index = _proxyMethods.size() - 1;
211
212     boolean retNeedsSerialization = needsSerialization(retType);
213     
214     if (retType.equals(void.class)) {
215     }
216     else if (! retNeedsSerialization) {
217       print("_ret = (");
218       printClass(retType);
219       print(")");
220     }
221     else {
222       print("Object _oret = ");
223     }
224
225     if (retType.isPrimitive())
226       print("com.caucho.ejb.JVMObject.to_" + retType.getName() + "(");
227
228     print("method" + index + ".invoke(obj, new Object[] {");
229     for (int i = 0; i < params.length; i++) {
230       if (i != 0)
231         print(", ");
232       if (needsSerialization(params[i])) {
233         print("(");
234         printClass(params[i]);
235         print(") ser.read()");
236       }
237       else if (params[i].isPrimitive())
238         printToObject("a" + i, params[i]);
239       else
240         print("a" + i);
241     }
242     if (retType.isPrimitive())
243       println("}));");
244     else
245       println("});");
246     
247     if (retNeedsSerialization) {
248       // println("System.out.println(_oret);");
249
println("ser.clear();");
250       println("ser.write(_oret);");
251       println("thread.setContextClassLoader(oldLoader);");
252       print("_ret = (");
253       printClass(method.getReturnType());
254       println(") ser.read();");
255     }
256
257     popDepth();
258     println("} catch (java.lang.IllegalAccessException e) {");
259     println(" throw com.caucho.ejb.EJBExceptionWrapper.createRuntime(e);");
260     println("} catch (java.lang.reflect.InvocationTargetException e) {");
261     println(" throw com.caucho.ejb.EJBExceptionWrapper.createRuntime(e);");
262     println("}");
263   }
264
265   void printToObject(String JavaDoc name, Class JavaDoc cl)
266     throws IOException JavaDoc
267   {
268     if (boolean.class.equals(cl))
269       print("new Boolean(" + name + ")");
270     else if (byte.class.equals(cl))
271       print("new Byte(" + name + ")");
272     else if (short.class.equals(cl))
273       print("new Short(" + name + ")");
274     else if (char.class.equals(cl))
275       print("new Character(" + name + ")");
276     else if (int.class.equals(cl))
277       print("new Integer(" + name + ")");
278     else if (long.class.equals(cl))
279       print("new Long(" + name + ")");
280     else if (float.class.equals(cl))
281       print("new Float(" + name + ")");
282     else if (double.class.equals(cl))
283       print("new Double(" + name + ")");
284     else
285       throw new RuntimeException JavaDoc(L.l("can't create object for type {0}",
286                                      cl.getName()));
287   }
288
289   /**
290    * Prints the class footer for the generated stub.
291    */

292   void printFooter()
293     throws IOException JavaDoc
294   {
295     for (int i = 0; i < _proxyMethods.size(); i++) {
296       println("static java.lang.reflect.Method method" + i + ";");
297     }
298     if (_proxyMethods.size() > 0) {
299       println("protected void _caucho_init_methods(Class cl)");
300       println("{");
301       pushDepth();
302       println("try {");
303       pushDepth();
304       for (int i = 0; i < _proxyMethods.size(); i++) {
305         Method JavaDoc method = _proxyMethods.get(i);
306         
307         print("method" + i + " = cl.getMethod(\"");
308         print(method.getName());
309         print("\", new Class[] {");
310         Class JavaDoc []paramTypes = method.getParameterTypes();
311         for (int j = 0; j < paramTypes.length; j++) {
312           if (j != 0)
313             print(", ");
314           printClass(paramTypes[j]);
315           print(".class");
316         }
317         println("});");
318       }
319       popDepth();
320       println("} catch (Exception e) {");
321       println(" com.caucho.ejb.EJBExceptionWrapper.createRuntime(e);");
322       println("}");
323       popDepth();
324       println("}");
325     }
326     
327     popDepth();
328     println("}");
329   }
330
331   /**
332    * Returns true if the class needs serialization.
333    *
334    * @param cl the class to test.
335    *
336    * @return true if the class needs serialization
337    */

338   boolean needsSerialization(Class JavaDoc cl)
339   {
340     if (cl.isPrimitive())
341       return false;
342     else if (! _isProxy && EJBObject JavaDoc.class.isAssignableFrom(cl))
343       return false;
344     else if (! _isProxy && EJBLocalObject JavaDoc.class.isAssignableFrom(cl))
345       return false;
346     else if (! _isProxy && EJBHome JavaDoc.class.isAssignableFrom(cl))
347       return false;
348     else if (! _isProxy && EJBLocalHome JavaDoc.class.isAssignableFrom(cl))
349       return false;
350     else
351       return _immutableClasses.get(cl) < 0;
352   }
353
354   /**
355    * Generates code for version changes.
356    */

357   protected void printVersionChange()
358     throws IOException JavaDoc
359   {
360     println("if (com.caucho.ejb.Version.getVersionId() != " +
361             com.caucho.ejb.Version.getVersionId() + ")");
362     println(" return true;");
363   }
364   
365   static {
366     _immutableClasses = new IntMap();
367     _immutableClasses.put(String JavaDoc.class, 1);
368     _immutableClasses.put(Byte JavaDoc.class, 1);
369     _immutableClasses.put(Character JavaDoc.class, 1);
370     _immutableClasses.put(Short JavaDoc.class, 1);
371     _immutableClasses.put(Integer JavaDoc.class, 1);
372     _immutableClasses.put(Long JavaDoc.class, 1);
373     _immutableClasses.put(Float JavaDoc.class, 1);
374     _immutableClasses.put(Double JavaDoc.class, 1);
375     _immutableClasses.put(Class JavaDoc.class, 1);
376   }
377 }
378
Popular Tags