1 4 5 9 10 package org.openlaszlo.remote; 11 12 import java.io.*; 13 import java.lang.reflect.*; 14 import java.util.*; 15 import java.lang.reflect.*; 16 import javax.servlet.http.*; 17 import org.openlaszlo.iv.flash.util.*; 18 import org.openlaszlo.iv.flash.api.action.*; 19 import org.openlaszlo.iv.flash.api.*; 20 import org.openlaszlo.utils.*; 21 import org.openlaszlo.xml.internal.*; 22 import org.apache.log4j.*; 23 import org.apache.commons.beanutils.PropertyUtils; 24 25 28 public class LZReturnObject 29 { 30 public static Logger mLogger = Logger.getLogger(LZReturnObject.class); 31 public static final int RETTYPE_POJO = 0; 32 public static final int RETTYPE_JAVA_BEAN = 1; 33 34 35 int mCount = 0; 36 int mSize = 4096; 37 FlashBuffer mBody = new FlashBuffer(mSize); 38 Program mProgram = new Program(mBody); 39 DataContext mDC; 40 int mSWFVersion; 41 int mObjRetType; 42 43 public LZReturnObject(String objectReturnType, int swfversion) { 44 mDC = new DataContext(); 45 mDC.setEncoding( swfversion == 5 ? "Cp1252" : "UTF-8" ); 46 if (objectReturnType == null) { 47 mObjRetType = RETTYPE_POJO; 48 } else if ("javabean".equals(objectReturnType)){ 49 mObjRetType = RETTYPE_JAVA_BEAN; 50 } else { 51 mObjRetType = RETTYPE_POJO; 52 } 53 } 54 55 void pushInteger(int i) { 56 mLogger.debug("pushInteger"); 57 mProgram.push(i); 58 } 59 60 void pushFloat(float f) { 61 mLogger.debug("pushFloat"); 62 mProgram.push(f); 63 } 64 65 void pushString(String s) { 66 mLogger.debug("pushString"); 67 DataCommon.pushStringData(s, mBody, mDC); 68 } 70 71 void pushDouble(double d) { 72 mLogger.debug("pushDouble"); 73 mBody.writeByte(Actions.PushData); 74 mBody.writeWord(8+1); 75 mBody.writeByte(6); 76 long dbits = Double.doubleToLongBits(d); 77 mBody.writeDWord((int)(dbits>>>32)); 78 mBody.writeDWord((int)(dbits&0xffffffffL)); 79 } 80 81 82 void pushBoolean(boolean b) { 83 mLogger.debug("pushBoolean"); 84 mBody.writeByte(Actions.PushData); 85 mBody.writeWord(1+1); 86 mBody.writeByte(5); 87 mBody.writeByte(b?1:0); 88 } 89 90 void pushArray(Object object) { 91 mLogger.debug("pushArray"); 92 int length = Array.getLength(object); 93 for (int i = length - 1; 0 <= i; i--) { 94 createReturnValue(Array.get(object, i)); 95 } 96 mProgram.push(length); 97 mBody.writeByte(Actions.InitArray); 98 } 99 100 void pushList(Object object) { 101 mLogger.debug("pushList"); 102 List list = (List)object; 103 int length = list.size(); 104 for (int i = length - 1; 0 <= i; i--) { 105 createReturnValue(list.get(i)); 106 } 107 mProgram.push(length); 108 mBody.writeByte(Actions.InitArray); 109 } 110 111 void pushNull() { 112 mBody.writeByte(Actions.PushData); 113 mBody.writeWord(0+1); 114 mBody.writeByte(2); 115 } 116 117 118 void pushObject(Object object) { 119 Class cl = object.getClass(); 120 121 String varname = "__tmp" + (mCount++); 123 String classname = cl.getName(); 124 125 mProgram.push(varname); 128 { 129 mProgram.push(0); mProgram.push("Object"); mProgram.newObject(); } 134 mProgram.setVar(); 135 136 137 mProgram.push(varname); 140 mProgram.getVar(); 141 mProgram.push("class"); 142 mProgram.push(classname); 143 mBody.writeByte(Actions.SetMember); 144 145 if (mObjRetType == RETTYPE_JAVA_BEAN) { 146 pushObjectJavaBean(object, varname); 147 } else { 148 pushObjectPOJO(object, varname); 149 } 150 151 mProgram.push(varname); 154 mProgram.getVar(); 155 } 156 157 160 void pushObjectPOJO(Object object, String varname) { 161 Class cl = object.getClass(); 162 Field[] fields = cl.getFields(); 163 for (int i=0; i < fields.length; i++) { 164 if (! Modifier.isPublic(fields[i].getModifiers())) 165 continue; 166 167 String fieldName = fields[i].getName(); 168 Object value; 169 try { 170 value = fields[i].get(object); 171 } catch (IllegalAccessException e) { 172 mLogger.error("IllegalAccessException", e); 173 continue; 174 } 175 if (mLogger.isDebugEnabled()) { 176 mLogger.debug("add field name " + fieldName + ", " + 177 (value != null ? value.getClass() : null) ); 178 } 179 mProgram.push(varname); 180 mProgram.getVar(); 181 mProgram.push(fieldName); 182 createReturnValue(value); 183 mBody.writeByte(Actions.SetMember); 184 } 185 } 186 187 190 void pushObjectJavaBean(Object object, String varname) { 191 Map beanProps = null; 194 try { 195 beanProps = PropertyUtils.describe(object); 197 } catch (IllegalAccessException e) { 198 mLogger.error("IllegalAccessException",e); 199 } catch (InvocationTargetException e) { 200 mLogger.error("InvocationTargetException",e); 201 } catch (NoSuchMethodException e) { 202 mLogger.error("NoSuchMethodException",e); 203 } 204 205 if (beanProps != null) { 206 Set keys = beanProps.keySet(); 207 Iterator iter = keys.iterator(); 208 while(iter.hasNext()){ 209 String fieldName = (String )iter.next(); 210 if(!"class".equals(fieldName)) { 212 Object value = beanProps.get(fieldName); 213 if (mLogger.isDebugEnabled()) { 214 mLogger.debug("add field name " + fieldName + ", " + 215 ((value!=null)?value.getClass():null)); 216 } 217 mProgram.push(varname); 218 mProgram.getVar(); 219 mProgram.push((String )fieldName); 220 createReturnValue(value); 221 mBody.writeByte(Actions.SetMember); 222 } 223 } 224 } 225 } 226 227 228 void pushMap(Map map) { 229 230 String varname = "__tmp" + (mCount++); 232 233 mProgram.push(varname); 236 { 237 mProgram.push(0); mProgram.push("Object"); mProgram.newObject(); } 242 mProgram.setVar(); 243 244 Iterator iter = map.keySet().iterator(); 245 246 while (iter.hasNext()) { 247 String key = (String )iter.next(); 248 249 mProgram.push(varname); 252 mProgram.getVar(); 253 mProgram.push(key); 254 createReturnValue(map.get(key)); 255 mBody.writeByte(Actions.SetMember); 256 } 257 258 259 mProgram.push(varname); 262 mProgram.getVar(); 263 } 264 265 268 void createReturnValue(Object object) { 269 mLogger.debug("createReturnValue"); 270 if (object == null) { 271 pushNull(); 272 return; 273 } 274 275 Class cl = object.getClass(); 276 if (cl.isArray()) { 277 pushArray(object); 278 } else if (List.class.isInstance(object)) { 279 pushList(object); 280 } else if (Map.class.isInstance(object)) { 281 pushMap((Map)object); 282 } else if (cl == Integer .class) { 283 pushInteger(((Integer )object).intValue()); 284 } else if (cl == Long .class) { 285 308 pushInteger(((Long )object).intValue()); 310 311 } else if (cl == Short .class) { 312 pushInteger(((Short )object).intValue()); 313 } else if (cl == Byte .class) { 314 pushInteger(((Byte )object).intValue()); 316 } else if (cl == Character .class) { 317 pushString(((Character )object).toString()); 318 } else if (cl == Float .class) { 319 pushFloat(((Float )object).floatValue()); 320 } else if (cl == Double .class) { 321 pushDouble(((Double )object).doubleValue()); 322 } else if (cl == Boolean .class) { 323 pushBoolean(((Boolean )object).booleanValue()); 324 } else if (cl == String .class) { 325 pushString((String )object); 326 } else { 327 pushObject(object); 328 } 329 } 330 331 332 335 public Program createObjectProgram(Object object) { 336 mLogger.debug("createObjectProgram(" + object + ")" ); 337 338 createReturnValue(object); 339 340 mProgram.push("_parent"); 343 mProgram.getVar(); 344 mProgram.push(2); 345 mProgram.push("_parent"); 346 mProgram.getVar(); 347 mProgram.push("loader"); 348 mBody.writeByte(Actions.GetMember); 349 mProgram.push("returnData"); 350 mProgram.callMethod(); 351 mProgram.pop(); 352 353 355 byte pooldata[] = DataCommon.makeStringPool(mDC); 357 358 final int MISC = 4096; 361 362 FlashBuffer out = new FlashBuffer(mBody.getSize() + pooldata.length + MISC); 364 out._writeByte( Actions.ConstantPool ); 366 out._writeWord( pooldata.length + 2 ); out._writeWord( mDC.cpool.size() ); out.writeArray( pooldata, 0, pooldata.length); 370 out.writeArray(mBody.getBuf(), 0, mBody.getSize()); 372 return new Program(out); 373 } 374 375 376 378 public static FlashFile createObjectFile(Object object, String objectReturnType, 379 int swfversion) 380 throws IOException { 381 mLogger.debug("createObjectFile(" + object + ", " + swfversion + ")" ); 382 FlashFile file = FlashFile.newFlashFile(); 384 Script s = new Script(1); 385 file.setMainScript(s); 386 file.setVersion(swfversion); 387 Frame frame = s.newFrame(); 388 Program program = new LZReturnObject(objectReturnType, swfversion) 389 .createObjectProgram(object); 390 frame.addFlashObject(new DoAction(program)); 391 return file; 392 } 393 394 399 public static byte[] createObject(Object object, String objectReturnType, 400 int swfversion) 401 throws IOException { 402 mLogger.debug("createObject(" + object + ")" ); 403 404 int i = 0; 405 try { 406 FlashFile file = createObjectFile(object, objectReturnType, 407 swfversion); 408 FlashOutput fob = file.generate(); 409 byte[] buf = new byte[fob.getSize()]; 410 System.arraycopy(fob.getBuf(), 0, buf, 0, fob.getSize()); 411 return buf; 412 } catch (IVException e) { 413 throw new ChainedException(e); 414 } catch (IOException e) { 415 mLogger.error("io error creating object SWF: " + e.getMessage()); 416 throw e; 417 } 418 } 419 420 } 421 | Popular Tags |