KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openlaszlo > remote > LZClientObject


1 /******************************************************************************
2  * LZClientObject.java
3  * ****************************************************************************/

4
5 /* J_LZ_COPYRIGHT_BEGIN *******************************************************
6 * Copyright 2001-2004 Laszlo Systems, Inc. All Rights Reserved. *
7 * Use is subject to license terms. *
8 * J_LZ_COPYRIGHT_END *********************************************************/

9
10 package org.openlaszlo.remote;
11
12 import java.io.*;
13 import java.lang.reflect.*;
14 import javax.servlet.http.*;
15 import org.openlaszlo.iv.flash.util.*;
16 import org.openlaszlo.iv.flash.api.action.*;
17 import org.openlaszlo.iv.flash.api.*;
18 import org.openlaszlo.utils.*;
19 import org.openlaszlo.xml.internal.DataCommon;
20 import org.openlaszlo.xml.internal.DataContext;
21 import org.apache.log4j.*;
22
23 /**
24  * Utility class to create object SWF based on a server object.
25  */

26 public class LZClientObject
27 {
28     public static Logger mLogger = Logger.getLogger(LZClientObject.class);
29
30     /**
31      */

32     public static Program createObjectProgram(String JavaDoc classname, String JavaDoc scope, Class JavaDoc c) {
33         if (mLogger.isDebugEnabled()) {
34             mLogger.debug("createObjectProgram(" + classname + "," + "," + scope + ","
35                           + c.getName() + ")" );
36         }
37
38         int size = 4096;
39         FlashBuffer body = new FlashBuffer(size);
40         Program program = new Program(body);
41         DataContext dc = new DataContext();
42
43         //------------------------------------------------------------
44
// Tells client data returned is an object
45
// this.__LZstub = true
46
program.push("__LZstubload");
47         program.push(1);
48
49
50         // SOAP specific information
51
// object.stubinfo
52
program.push("stubinfo");
53         {
54             //------------------------------------------------------------
55
// this.remoteClass = classname
56
program.push("remoteClass");
57             DataCommon.pushStringData(classname, body, dc);
58         }
59         program.push(1);
60         body.writeByte(Actions.InitObject);
61
62
63         // object.stub
64
program.push("stub");
65         {
66             int count = 0;
67             boolean onlyStatic = "staticobject".equals(scope);
68
69             //------------------------------------------------------------
70
// Create methods for object
71
Method[] methods = c.getMethods();
72             for (int i=0; i < methods.length; i++) {
73
74                 // Skip Object methods
75
if (methods[i].getDeclaringClass() == Object JavaDoc.class) {
76                     continue;
77                 }
78
79                 // Check if we only want static methods
80
if (onlyStatic &&
81                     ! Modifier.isStatic(methods[i].getModifiers())) {
82                     continue;
83                 }
84
85                 // Skip toString method.
86
String JavaDoc methodName = methods[i].getName();
87                 if ("toString".equals(methodName)) {
88                     continue;
89                 }
90
91                 count++;
92
93                 //------------------------------------------------------------
94
//
95
DataCommon.pushStringData(methodName, body, dc);
96                 body.writeByte(Actions.DefineFunction);
97                 body.writeWord(5); // length of header (1 byte + 2 words (2bytes))
98
body.writeByte(0); // function name string (if empty, it is
99
// anonymous)
100
body.writeWord(0); // number of parameters
101
{
102                     // Check to see if method's last two parameters are
103
// HttpServletRequest and HttpServletResponse.
104
Class JavaDoc[] params = methods[i].getParameterTypes();
105                     int len = params.length;
106                     boolean doreq = // next to last or last argument
107
(len > 1 && params[len-2] == HttpServletRequest.class) ||
108                         (len > 0 && params[len-1] == HttpServletRequest.class);
109                     boolean dores = // should be last argument
110
(len > 0 && params[len-1] == HttpServletResponse.class);
111
112                     FlashBuffer fbuf = new FlashBuffer(500);
113                     Program fprog = new Program(fbuf);
114
115                     // arguments.callee.args gets set in the client and includes
116
// secure and secureport information.
117
//
118
// var args = arguments.callee.args;
119
DataCommon.pushStringData("args", fbuf, dc);
120                     {
121                         DataCommon.pushStringData("arguments", fbuf, dc);
122                         fprog.getVar();
123                         DataCommon.pushStringData("callee", fbuf, dc);
124                         fbuf.writeByte(Actions.GetMember);
125                         DataCommon.pushStringData("args", fbuf, dc);
126                         fbuf.writeByte(Actions.GetMember);
127                     }
128                     fprog.setVar();
129
130                     // _root.LzRemote.invoke(
131
// arguments,
132
// delegate,
133
// classname,
134
// classname + "." + methodName,
135
// { op: 'session', doreq..., dores... },
136
// this.secure,
137
// this.secureport
138
// );
139

140                     // 5. secureport
141
DataCommon.pushStringData("args", fbuf, dc);
142                     fprog.getVar();
143                     DataCommon.pushStringData("secureport", fbuf, dc);
144                     fbuf.writeByte(Actions.GetMember);
145
146                     // 4. secure
147
DataCommon.pushStringData("args", fbuf, dc);
148                     fprog.getVar();
149                     DataCommon.pushStringData("secure", fbuf, dc);
150                     fbuf.writeByte(Actions.GetMember);
151
152                     // 3. opts
153
int optcount = 0;
154                     {
155                         // { op: 'invoke', oname: varname, scope: scope,
156
// objectreturntype: objectreturntype,
157
// doreq: TBD, dores: TBD}
158
DataCommon.pushStringData("op", fbuf, dc);
159                         DataCommon.pushStringData("invoke", fbuf, dc);
160                         optcount++;
161
162                         DataCommon.pushStringData("objectreturntype", fbuf, dc);
163                         {
164                             DataCommon.pushStringData("args", fbuf, dc);
165                             fprog.getVar();
166                             DataCommon.pushStringData("objectreturntype", fbuf, dc);
167                             fbuf.writeByte(Actions.GetMember);
168                         }
169                         optcount++;
170
171                         DataCommon.pushStringData("oname", fbuf, dc);
172                         {
173                             DataCommon.pushStringData("args", fbuf, dc);
174                             fprog.getVar();
175                             DataCommon.pushStringData("attributename", fbuf, dc);
176                             fbuf.writeByte(Actions.GetMember);
177                         }
178                         optcount++;
179
180                         DataCommon.pushStringData("scope", fbuf, dc);
181                         {
182                             DataCommon.pushStringData("args", fbuf, dc);
183                             fprog.getVar();
184                             DataCommon.pushStringData("scope", fbuf, dc);
185                             fbuf.writeByte(Actions.GetMember);
186                         }
187                         optcount++;
188
189                         DataCommon.pushStringData("methodname", fbuf, dc);
190                         DataCommon.pushStringData(classname + "." + methodName,
191                                                   fbuf, dc);
192                         optcount++;
193
194                         DataCommon.pushStringData("classname", fbuf, dc);
195                         DataCommon.pushStringData(classname, fbuf, dc);
196                         optcount++;
197
198                         if (doreq) {
199                             DataCommon.pushStringData("doreq", fbuf, dc);
200                             fprog.push(1);
201                             optcount++;
202                         }
203                         if (dores) {
204                             DataCommon.pushStringData("dores", fbuf, dc);
205                             fprog.push(1);
206                             optcount++;
207                         }
208                     }
209                     fprog.push(optcount); // # of object values
210
fbuf.writeByte(Actions.InitObject);
211
212                     // 2. arguments[0] (should be array of arguments)
213
DataCommon.pushStringData("arguments", fbuf, dc);
214                     fprog.getVar();
215                     fprog.push(0);
216                     fbuf.writeByte(Actions.GetMember);
217
218                     // 1. arguments[1] (should be delegate)
219
DataCommon.pushStringData("arguments", fbuf, dc);
220                     fprog.getVar();
221                     fprog.push(1);
222                     fbuf.writeByte(Actions.GetMember);
223
224                     // Number of parameters
225
fprog.push(5);
226
227                     // call function
228
DataCommon.pushStringData("_root", fbuf, dc);
229                     fprog.getVar();
230                     DataCommon.pushStringData("LzJavaRPCService", fbuf, dc);
231                     fbuf.writeByte(Actions.GetMember);
232                     DataCommon.pushStringData("invoke", fbuf, dc);
233                     fprog.callMethod();
234
235                     // return seqnum from invoke()
236
fbuf.writeByte(Actions.Return);
237
238                     body.writeWord(fbuf.pos); // length of defined function body
239
body.writeFOB(fbuf);
240                 }
241             }
242             program.push(count);
243             body.writeByte(Actions.InitObject);
244         }
245
246
247         program.push(3);
248         body.writeByte(Actions.InitObject);
249
250
251         //------------------------------------------------------------
252
// call into the viewsystem
253
program.push("_parent");
254         program.getVar();
255         program.push(2);
256         program.push("_parent");
257         program.getVar();
258         program.push("loader");
259         body.writeByte(Actions.GetMember);
260         program.push("returnData");
261         program.callMethod();
262         program.pop();
263
264         // Collect the string dictionary data
265
byte pooldata[] = DataCommon.makeStringPool(dc);
266         // 'out' is the main FlashBuffer for composing the output file
267
final int MISC = 64;
268         FlashBuffer out = new FlashBuffer(body.getSize() + pooldata.length + MISC);
269         // Write out string constant pool
270
out.writeByte( Actions.ConstantPool );
271         out.writeWord( pooldata.length + 2 ); // number of bytes in pool data + int (# strings)
272
out.writeWord( dc.cpool.size() ); // number of strings in pool
273
out.writeArray( pooldata, 0, pooldata.length); // copy the data
274
// Write out the code to build nodes
275
out.writeArray(body.getBuf(), 0, body.getSize());
276
277         return new Program(out);
278     }
279
280
281     /**
282      */

283     public static FlashFile createObjectFile(String JavaDoc classname, String JavaDoc scope, Class JavaDoc c,
284                                              int swfversion)
285         throws IOException {
286         if (mLogger.isDebugEnabled()) {
287             mLogger.debug("createObjectFile(" + classname + "," + c.getName() + ")" );
288         }
289         // Create FlashFile object nd include action bytes
290
FlashFile file = FlashFile.newFlashFile();
291         Script s = new Script(1);
292         file.setMainScript(s);
293         file.setVersion(swfversion);
294         Frame frame = s.newFrame();
295         Program program = createObjectProgram(classname, scope, c);
296         frame.addFlashObject(new DoAction(program));
297         return file;
298     }
299
300     /**
301      */

302     public static byte[] createObject(String JavaDoc classname, String JavaDoc scope, int swfversion)
303         throws IOException {
304         if (mLogger.isDebugEnabled()) {
305             mLogger.debug("createObject(" + classname + "," + scope + ")" );
306         }
307
308         Class JavaDoc c;
309         try {
310             c = Class.forName(classname);
311         } catch (ClassNotFoundException JavaDoc e) {
312             throw new RuntimeException JavaDoc("Can't find class " + classname);
313         }
314
315         int i = 0;
316         try {
317             FlashFile file = createObjectFile(classname, scope, c, swfversion);
318             FlashOutput fob = file.generate();
319             byte[] buf = new byte[fob.getSize()];
320             System.arraycopy(fob.getBuf(), 0, buf, 0, fob.getSize());
321             return buf;
322         } catch (IVException e) {
323             throw new ChainedException(e);
324         } catch (IOException e) {
325             mLogger.error("io error creating object SWF: " + e.getMessage());
326             throw e;
327         }
328     }
329
330 }
331
Popular Tags