KickJava   Java API By Example, From Geeks To Geeks.

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

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

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

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

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

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

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

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

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