KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > ejb > hessian > HessianSkeletonGenerator


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.hessian;
30
31 import com.caucho.make.ClassDependency;
32 import com.caucho.util.IntMap;
33 import com.caucho.vfs.Path;
34 import com.caucho.vfs.PersistentDependency;
35
36 import java.io.IOException JavaDoc;
37 import java.lang.reflect.Method JavaDoc;
38 import java.util.ArrayList JavaDoc;
39 import java.util.Iterator JavaDoc;
40
41 /**
42  * Skeleton generator code for both Home and Remote interfaces.
43  */

44 class HessianSkeletonGenerator extends MarshalGenerator {
45   Class JavaDoc _cl;
46   String JavaDoc _objClass;
47   String JavaDoc _fullName;
48   String JavaDoc _pkg;
49   String JavaDoc _className;
50
51   protected int _unique;
52   
53   protected ArrayList JavaDoc<Class JavaDoc> _marshallClasses;
54   protected ArrayList JavaDoc<Class JavaDoc> _unmarshallClasses;
55   
56   protected ArrayList JavaDoc<Class JavaDoc> _marshallArrays;
57   protected ArrayList JavaDoc<Class JavaDoc> _unmarshallArrays;
58   protected Class JavaDoc _interfaceClass;
59   protected ArrayList JavaDoc<PersistentDependency> _dependList;
60
61   /**
62    * Creates a skeleton generator for a given bean configuration.
63    */

64   HessianSkeletonGenerator(Class JavaDoc interfaceClass)
65   {
66     _interfaceClass = interfaceClass;
67     
68     _dependList = new ArrayList JavaDoc<PersistentDependency>();
69
70     _dependList.add(new ClassDependency(_interfaceClass));
71   }
72
73   /**
74    * Creates a home interface.
75    */

76   static Class JavaDoc generate(Class JavaDoc interfaceClass, Path workDir)
77     throws Exception JavaDoc
78   {
79     HessianSkeletonGenerator gen = new HessianSkeletonGenerator(interfaceClass);
80     gen.setClassDir(workDir);
81
82     gen.setFullClassName("_ejb." + interfaceClass.getName() + "__HessianSkel");
83
84     Class JavaDoc cl = gen.preload();
85     if (cl != null)
86       return cl;
87
88     gen.generate();
89     return gen.compile();
90   }
91
92   /**
93    * Generates the Java source code for the home skeleton.
94    */

95   public void generateJava()
96     throws IOException JavaDoc
97   {
98     ArrayList JavaDoc<Method JavaDoc> methodList = new ArrayList JavaDoc<Method JavaDoc>();
99
100     Method JavaDoc []methods = _interfaceClass.getMethods();
101     for (int i = 0; i < methods.length; i++) {
102       String JavaDoc className = methods[i].getDeclaringClass().getName();
103       String JavaDoc methodName = methods[i].getName();
104       
105       methodList.add(methods[i]);
106     }
107     
108     printHeader();
109     
110     IntMap methodMap = printDispatcher(methodList);
111
112     printDependList(_dependList);
113     
114     printFooter(methodMap);
115   }
116
117   /**
118    * Prints the header of the generated class.
119    */

120   void printHeader()
121     throws IOException JavaDoc
122   {
123     if (getPackageName() != null)
124       println("package " + getPackageName() + ";");
125
126     println();
127     println("import java.io.*;");
128     println("import com.caucho.util.*;");
129     println("import com.caucho.ejb.hessian.*;");
130     println("import com.caucho.hessian.io.*;");
131     println("import " + _interfaceClass.getName() + ";");
132
133     println();
134     print("public class " + getClassName() + " extends com.caucho.ejb.hessian.HessianSkeleton");
135     println(" {");
136     
137     pushDepth();
138
139     println("private " + _interfaceClass.getName() + " obj;");
140     println();
141     println("protected void _setObject(Object o)");
142     println("{");
143     println(" obj = (" + _interfaceClass.getName() + ") o;");
144     println("}");
145   }
146
147   /**
148    * Creates the dispatch code.
149    *
150    * @param methodMap a hash map from method names to methods.
151    */

152   protected IntMap printDispatcher(ArrayList JavaDoc<Method JavaDoc> methods)
153     throws IOException JavaDoc
154   {
155     IntMap map = new IntMap();
156     
157     println();
158     print("protected void _execute(CharBuffer method, HessianInput in, HessianOutput out, com.caucho.ejb.xa.TransactionContext xa)");
159     println(" throws Throwable");
160     println("{");
161     pushDepth();
162     println("switch (methods.get(method)) {");
163
164     int i = 0;
165     for (; i < methods.size(); i++) {
166       Method JavaDoc method = methods.get(i);
167
168       if (map.get(method.getName()) < 0)
169         map.put(method.getName(), i);
170       
171       map.put(mangleMethodName(method.getName(), method, false), i);
172
173       if (i > 0)
174         println();
175       println("case " + i + ":");
176       pushDepth();
177       println("{");
178       pushDepth();
179       
180       printUnmarshal(method.getName(), method.getParameterTypes(),
181                      method.getReturnType());
182
183       println("break;");
184       popDepth();
185       println("}");
186       popDepth();
187     }
188
189     /*
190     printMetaMethod(map, i++, "getAttribute",
191                     new Class[] { String.class },
192                     String.class);
193     */

194
195     println("default:");
196     println(" _executeUnknown(method, in, out);");
197     println(" break;");
198     println("}");
199     popDepth();
200     println("}");
201
202     return map;
203   }
204
205   /**
206    * Print the unmarshalling and marshalling code for a single method.
207    *
208    * @param method the reflected method to define code.
209    */

210   void printUnmarshal(String JavaDoc methodName, Class JavaDoc []param, Class JavaDoc retType)
211     throws IOException JavaDoc
212   {
213     for (int i = 0; i < param.length; i++) {
214       String JavaDoc var = "_arg" + i;
215       printClass(param[i]);
216       print(" " + var + " = ");
217       printUnmarshalType(param[i]);
218     }
219
220     println("in.completeCall();");
221
222     if (! retType.getName().equals("void")) {
223       printClass(retType);
224       print(" _ret = ");
225     }
226
227     printCall("obj", methodName, param);
228
229     println("startReply(out, xa);");
230
231     if (! retType.equals(void.class))
232       printMarshalType(retType, "_ret");
233     else
234       println("out.writeNull();");
235     
236     println("out.completeReply();");
237   }
238
239   /**
240    * Prints a call to the underlying objects.
241    *
242    * @param objName the underlying object name
243    * @param method the underlying method
244    */

245   void printCall(String JavaDoc objName, String JavaDoc methodName, Class JavaDoc []param)
246     throws IOException JavaDoc
247   {
248     print(objName);
249     print(".");
250     print(methodName);
251     print("(");
252     for (int i = 0; i < param.length; i++) {
253       if (i != 0)
254         print(", ");
255       print("_arg" + i);
256     }
257     println(");");
258   }
259
260   /**
261    * Print the unmarshalling and marshalling code for a meta method.
262    *
263    * @param method the reflected method to define code.
264    */

265   void printMetaMethod(IntMap map, int index,
266                        String JavaDoc methodName, Class JavaDoc []param, Class JavaDoc retType)
267     throws IOException JavaDoc
268   {
269     map.put("_hessian_" + methodName, index);
270     map.put("_hessian_" + mangleMethodName(methodName, param, true), index);
271
272     println("case " + index + ":");
273     println("{");
274     pushDepth();
275     
276     for (int i = 0; i < param.length; i++) {
277       String JavaDoc var = "_arg" + i;
278       printClass(param[i]);
279       println(" " + var + " = ");
280       printUnmarshalType(param[i]);
281     }
282
283     println("is.expectEndTag(\"hessian:call\");");
284     
285     if (! retType.getName().equals("void")) {
286       printClass(retType);
287       println(" _ret;");
288     }
289
290     if (! retType.getName().equals("void")) {
291       print("_ret = ");
292     }
293
294     printCall("this", methodName, param);
295     
296     println("os.print(\"<hessian:reply><value>\");");
297
298     if (! retType.equals(void.class))
299       printMarshalType(retType, "_ret");
300     else
301       print("os.print(\"<null></null>\");");
302     
303     println("os.print(\"</value></hessian:reply>\");");
304
305     println("break;");
306     popDepth();
307     println("}");
308   }
309
310   /**
311    * Returns the externally callable method name.
312    */

313   String JavaDoc getMethodName(Method JavaDoc method)
314   {
315     return method.getName();
316   }
317
318   /**
319    * Prints the code at the end of the class to define the static constants.
320    */

321   protected void printFooter(IntMap methodMap)
322     throws IOException JavaDoc
323   {
324     println("static private IntMap methods = new IntMap();");
325     println("static {");
326     pushDepth();
327
328     Iterator JavaDoc keys = methodMap.iterator();
329     while (keys.hasNext()) {
330       String JavaDoc name = (String JavaDoc) keys.next();
331       int value = methodMap.get(name);
332       
333       println("methods.put(new CharBuffer(\"" + name + "\")," + value + ");");
334     }
335     popDepth();
336     println("}");
337     popDepth();
338     println("}");
339   }
340 }
341
Popular Tags