KickJava   Java API By Example, From Geeks To Geeks.

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


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.java.AbstractGenerator;
32 import com.caucho.loader.DynamicClassLoader;
33 import com.caucho.util.CharBuffer;
34 import com.caucho.util.IntMap;
35 import com.caucho.vfs.Path;
36
37 import java.io.IOException JavaDoc;
38 import java.lang.reflect.Method JavaDoc;
39 import java.util.ArrayList JavaDoc;
40
41 /**
42  * Base class for generating code to marshal and unmarshal sml-rpc calls.
43  */

44 abstract class MarshalGenerator extends AbstractGenerator {
45   // Classes which can be safely passed by reference because they're
46
// immutable and part of the JDK
47
static IntMap immutableClasses;
48   
49   protected static Class JavaDoc readerClass;
50   protected static Class JavaDoc inputStreamClass;
51   protected static Class JavaDoc remoteClass;
52   protected static Class JavaDoc nodeClass;
53   
54   static {
55     readerClass = java.io.Reader JavaDoc.class;
56     inputStreamClass = java.io.InputStream JavaDoc.class;
57     remoteClass = java.rmi.Remote JavaDoc.class;
58     nodeClass = org.w3c.dom.Node JavaDoc.class;
59   }
60   
61   protected Class JavaDoc _cl;
62   String JavaDoc objClass;
63   String JavaDoc fullName;
64   String JavaDoc pkg;
65   String JavaDoc className;
66
67   protected int unique;
68   
69   protected ArrayList JavaDoc marshallClasses;
70   protected ArrayList JavaDoc unmarshallClasses;
71   
72   protected ArrayList JavaDoc marshallArrays;
73   protected ArrayList JavaDoc unmarshallArrays;
74
75   /**
76    * Initialize the generated classname.
77    *
78    * @param beanClass the bean which needs the stub/skeleton
79    *
80    * @return the path to the file to be generated
81    */

82   Path initClassNames(Class JavaDoc beanClass, String JavaDoc suffix)
83     throws Exception JavaDoc
84   {
85     ClassLoader JavaDoc parentLoader = getParentLoader();
86     
87     if (parentLoader instanceof DynamicClassLoader) {
88       DynamicClassLoader dcl = (DynamicClassLoader) parentLoader;
89
90       dcl.make();
91     }
92
93     Path workPath = getClassDir();
94
95     _cl = beanClass;
96
97     fullName = _cl.getName() + suffix;
98
99     objClass = _cl.getName();
100     int p = objClass.lastIndexOf('.');
101     if (p > 0)
102       objClass = objClass.substring(p + 1);
103     
104     p = fullName.lastIndexOf('.');
105     if (p > 0) {
106       pkg = fullName.substring(0, p);
107       className = fullName.substring(p + 1);
108     }
109     else
110       className = fullName;
111
112     Path path = workPath.lookup(fullName.replace('.', '/') + ".java");
113     path.getParent().mkdirs();
114
115     return path;
116   }
117
118   /**
119    * Creates a unique mangled method name based on the method name and
120    * the method parameters.
121    *
122    * @param name the base method name
123    * @param method the method to mangle
124    * @param isFull if true, mangle the full classname
125    *
126    * @return a mangled string.
127    */

128   protected String JavaDoc mangleMethodName(String JavaDoc name, Method JavaDoc method, boolean isFull)
129   {
130     CharBuffer cb = CharBuffer.allocate();
131     
132     cb.append(name);
133     
134     Class JavaDoc []params = method.getParameterTypes();
135     for (int i = 0; i < params.length; i++) {
136       cb.append('_');
137       mangleClass(cb, params[i], isFull);
138     }
139
140     return cb.close();
141   }
142
143   /**
144    * Creates a unique mangled method name based on the method name and
145    * the method parameters.
146    *
147    * @param name the base method name
148    * @param method the method to mangle
149    * @param isFull if true, mangle the full classname
150    *
151    * @return a mangled string.
152    */

153   protected String JavaDoc mangleMethodName(String JavaDoc name, Class JavaDoc []param, boolean isFull)
154   {
155     CharBuffer cb = CharBuffer.allocate();
156     
157     cb.append(name);
158     
159     for (int i = 0; i < param.length; i++) {
160       cb.append('_');
161       mangleClass(cb, param[i], isFull);
162     }
163
164     return cb.close();
165   }
166
167   /**
168    * Mangles a classname.
169    */

170   private void mangleClass(CharBuffer cb, Class JavaDoc cl, boolean isFull)
171   {
172     String JavaDoc name = cl.getName();
173
174     if (name.equals("boolean"))
175       cb.append("boolean");
176     else if (name.equals("int") ||
177              name.equals("short") ||
178              name.equals("byte"))
179       cb.append("int");
180     else if (name.equals("long"))
181       cb.append("long");
182     else if (name.equals("double") || name.equals("float"))
183       cb.append("double");
184     else if (name.equals("java.lang.String") ||
185              name.equals("com.caucho.util.CharBuffer") ||
186              name.equals("char") ||
187              name.equals("java.io.Reader"))
188       cb.append("string");
189     else if (name.equals("java.util.Date") ||
190              name.equals("com.caucho.util.QDate"))
191       cb.append("date");
192     else if (inputStreamClass.isAssignableFrom(cl) ||
193              name.equals("[B"))
194       cb.append("binary");
195     else if (cl.isArray()) {
196       cb.append("[");
197       mangleClass(cb, cl.getComponentType(), isFull);
198     }
199     else if (name.equals("org.w3c.dom.Node") ||
200              name.equals("org.w3c.dom.Element") ||
201              name.equals("org.w3c.dom.Document"))
202       cb.append("xml");
203     else if (isFull)
204       cb.append(name);
205     else {
206       int p = name.lastIndexOf('.');
207       if (p > 0)
208         cb.append(name.substring(p + 1));
209       else
210         cb.append(name);
211     }
212   }
213
214   /**
215    * Prints a method declaration with a given name.
216    *
217    * @param name the name to use for the generated method
218    * @param method the method to override
219    */

220   protected void printMethodDeclaration(String JavaDoc name, Method JavaDoc method)
221     throws IOException JavaDoc
222   {
223     Class JavaDoc ret = method.getReturnType();
224     Class JavaDoc []params = method.getParameterTypes();
225
226     Class JavaDoc []exns = method.getExceptionTypes();
227
228     println();
229     print("public ");
230     printClass(ret);
231     print(" " + name + "(");
232     for (int i = 0; i < params.length; i++) {
233       if (i != 0)
234         print(", ");
235       printClass(params[i]);
236       print(" _arg" + i);
237     }
238     println(")");
239     if (exns.length > 0)
240       print(" throws ");
241     for (int i = 0; i < exns.length; i++) {
242       if (i != 0)
243         print(", ");
244       printClass(exns[i]);
245     }
246     if (exns.length > 0)
247       println();
248   }
249
250   /**
251    * Unmarshal the reading of a single variable, knowing the result
252    * type.
253    *
254    * @param var the generated java variable which will receive the data.
255    * @param cl the class of the target variable.
256    */

257   protected void printUnmarshalType(Class JavaDoc cl)
258     throws IOException JavaDoc
259   {
260     String JavaDoc name = cl.getName();
261
262     if (cl.equals(boolean.class)) {
263       println("in.readBoolean();");
264     }
265     else if (cl.equals(int.class)) {
266       println("in.readInt();");
267     }
268     else if (cl.equals(short.class) ||
269              cl.equals(char.class) ||
270              cl.equals(byte.class)) {
271       println("(" + name + ") in.readInt();");
272     }
273     else if (cl.equals(long.class)) {
274       println("in.readLong();");
275     }
276     else if (cl.equals(double.class)) {
277       println("in.readDouble();");
278     }
279     else if (cl.equals(float.class)) {
280       println("(" + name + ") in.readDouble();");
281     }
282     else if (cl.equals(String JavaDoc.class))
283       println("in.readString();");
284     else if (cl.equals(java.util.Date JavaDoc.class)) {
285       println("new java.util.Date(in.readUTCDate());");
286     }
287     else if (cl.equals(byte[].class)) {
288       println("in.readBytes();");
289     }
290     else if (org.w3c.dom.Node JavaDoc.class.isAssignableFrom(cl)) {
291       println("in.readNode();");
292     }
293     else if (cl.equals(java.lang.Object JavaDoc.class)) {
294       println("in.readObject();");
295     }
296     else {
297       print("(");
298       printClass(cl);
299       print(") in.readObject(");
300       printClass(cl);
301       println(".class);");
302     }
303   }
304
305   protected void printMarshalType(Class JavaDoc cl, String JavaDoc var)
306     throws IOException JavaDoc
307   {
308     String JavaDoc name = cl.getName();
309
310     if (cl.equals(void.class)) {
311       println("out.writeNull();");
312     }
313     else if (cl.equals(boolean.class)) {
314       println("out.writeBoolean(" + var + ");");
315     }
316     else if (cl.equals(int.class) ||
317              cl.equals(short.class) ||
318              cl.equals(char.class) ||
319              cl.equals(byte.class)) {
320       println("out.writeInt(" + var + ");");
321     }
322     else if (cl.equals(long.class)) {
323       println("out.writeLong(" + var + ");");
324     }
325     else if (cl.equals(double.class) || cl.equals(float.class)) {
326       println("out.writeDouble(" + var + ");");
327     }
328     else if (cl.equals(String JavaDoc.class)) {
329       println("out.writeString(" + var + ");");
330     }
331     else if (cl.equals(java.util.Date JavaDoc.class)) {
332       println("out.writeUTCDate(" + var + " == null ? 0 : " + var + ".getTime());");
333     }
334     else if (org.w3c.dom.Node JavaDoc.class.isAssignableFrom(cl)) {
335       println("out.writeXml(" + var + ");");
336     }
337     else if (cl.equals(byte[].class)) {
338       println("out.writeBytes(" + var + ");");
339     }
340     else {
341       println("out.writeObject(" + var + ");");
342     }
343   }
344
345   /**
346    * Returns true if the class needs serialization.
347    *
348    * @param cl the class to test.
349    *
350    * @return true if the class needs serialization
351    */

352   boolean needsSerialization(Class JavaDoc cl)
353   {
354     if (cl.isPrimitive())
355       return false;
356     else
357       return immutableClasses.get(cl) < 0;
358   }
359
360   public void printClass(Class JavaDoc cl)
361     throws IOException JavaDoc
362   {
363     if (! cl.isArray())
364       print(cl.getName());
365     else {
366       printClass(cl.getComponentType());
367       print("[]");
368     }
369   }
370
371   protected void printNewArray(Class JavaDoc cl)
372     throws IOException JavaDoc
373   {
374     if (! cl.isArray()) {
375       print(cl.getName());
376       print("[length]");
377     }
378     else {
379       printNewArray(cl.getComponentType());
380       print("[]");
381     }
382   }
383
384   static {
385     immutableClasses = new IntMap();
386     immutableClasses.put(String JavaDoc.class, 1);
387     immutableClasses.put(Byte JavaDoc.class, 1);
388     immutableClasses.put(Character JavaDoc.class, 1);
389     immutableClasses.put(Short JavaDoc.class, 1);
390     immutableClasses.put(Integer JavaDoc.class, 1);
391     immutableClasses.put(Long JavaDoc.class, 1);
392     immutableClasses.put(Float JavaDoc.class, 1);
393     immutableClasses.put(Double JavaDoc.class, 1);
394     immutableClasses.put(Class JavaDoc.class, 1);
395   }
396 }
397
Popular Tags