1 48 49 package com.caucho.hessian.io; 50 51 import java.io.IOException ; 52 import java.lang.reflect.Constructor ; 53 import java.lang.reflect.Field ; 54 import java.lang.reflect.InvocationTargetException ; 55 import java.lang.reflect.Method ; 56 import java.lang.reflect.Modifier ; 57 import java.util.HashMap ; 58 59 62 public class JavaDeserializer extends AbstractMapDeserializer { 63 private Class _type; 64 private HashMap _fieldMap; 65 private Method _readResolve; 66 private Constructor _constructor; 67 private Object []_constructorArgs; 68 69 public JavaDeserializer(Class cl) 70 { 71 _type = cl; 72 _fieldMap = getFieldMap(cl); 73 74 _readResolve = getReadResolve(cl); 75 76 if (_readResolve != null) { 77 _readResolve.setAccessible(true); 78 } 79 80 Constructor []constructors = cl.getDeclaredConstructors(); 81 long bestCost = Long.MAX_VALUE; 82 83 for (int i = 0; i < constructors.length; i++) { 84 Class []param = constructors[i].getParameterTypes(); 85 long cost = 0; 86 87 for (int j = 0; j < param.length; j++) { 88 cost = 4 * cost; 89 90 if (Object .class.equals(param[j])) 91 cost += 1; 92 else if (String .class.equals(param[j])) 93 cost += 2; 94 else if (int.class.equals(param[j])) 95 cost += 3; 96 else if (long.class.equals(param[j])) 97 cost += 4; 98 else if (param[j].isPrimitive()) 99 cost += 5; 100 else 101 cost += 6; 102 } 103 104 if (cost < 0 || cost > (1 << 48)) 105 cost = 1 << 48; 106 107 cost += param.length << 48; 108 109 if (cost < bestCost) { 110 _constructor = constructors[i]; 111 bestCost = cost; 112 } 113 } 114 115 if (_constructor != null) { 116 _constructor.setAccessible(true); 117 Class []params = _constructor.getParameterTypes(); 118 _constructorArgs = new Object [params.length]; 119 for (int i = 0; i < params.length; i++) { 120 _constructorArgs[i] = getParamArg(params[i]); 121 } 122 } 123 } 124 125 public Class getType() 126 { 127 return _type; 128 } 129 130 public Object readMap(AbstractHessianInput in) 131 throws IOException 132 { 133 try { 134 Object obj = instantiate(); 135 136 return readMap(in, obj); 137 } catch (IOException e) { 138 throw e; 139 } catch (RuntimeException e) { 140 throw e; 141 } catch (Exception e) { 142 throw new IOExceptionWrapper(_type.getName() + ":" + e.getMessage(), e); 143 } 144 } 145 146 public Object readObject(AbstractHessianInput in, String []fieldNames) 147 throws IOException 148 { 149 try { 150 Object obj = instantiate(); 151 152 return readObject(in, obj, fieldNames); 153 } catch (IOException e) { 154 throw e; 155 } catch (RuntimeException e) { 156 throw e; 157 } catch (Exception e) { 158 throw new IOExceptionWrapper(_type.getName() + ":" + e.getMessage(), e); 159 } 160 } 161 162 165 protected Method getReadResolve(Class cl) 166 { 167 for (; cl != null; cl = cl.getSuperclass()) { 168 Method []methods = cl.getDeclaredMethods(); 169 170 for (int i = 0; i < methods.length; i++) { 171 Method method = methods[i]; 172 173 if (method.getName().equals("readResolve") && 174 method.getParameterTypes().length == 0) 175 return method; 176 } 177 } 178 179 return null; 180 } 181 182 public Object readMap(AbstractHessianInput in, Object obj) 183 throws IOException 184 { 185 try { 186 int ref = in.addRef(obj); 187 188 while (! in.isEnd()) { 189 Object key = in.readObject(); 190 191 FieldDeserializer deser = (FieldDeserializer) _fieldMap.get(key); 192 193 if (deser != null) 194 deser.deserialize(in, obj); 195 else 196 in.readObject(); 197 } 198 199 in.readMapEnd(); 200 201 Object resolve = resolve(obj); 202 203 if (obj != resolve) 204 in.setRef(ref, resolve); 205 206 return resolve; 207 } catch (IOException e) { 208 throw e; 209 } catch (Exception e) { 210 throw new IOExceptionWrapper(e); 211 } 212 } 213 214 public Object readObject(AbstractHessianInput in, 215 Object obj, 216 String []fieldNames) 217 throws IOException 218 { 219 try { 220 int ref = in.addRef(obj); 221 222 for (int i = 0; i < fieldNames.length; i++) { 223 String name = fieldNames[i]; 224 225 FieldDeserializer deser = (FieldDeserializer) _fieldMap.get(name); 226 227 if (deser != null) 228 deser.deserialize(in, obj); 229 else 230 in.readObject(); 231 } 232 233 Object resolve = resolve(obj); 234 235 if (obj != resolve) 236 in.setRef(ref, resolve); 237 238 return resolve; 239 } catch (IOException e) { 240 throw e; 241 } catch (Exception e) { 242 throw new IOExceptionWrapper(obj.getClass().getName() + ":" + e, e); 243 } 244 } 245 246 private Object resolve(Object obj) 247 throws Exception 248 { 249 try { 251 if (_readResolve != null) 252 return _readResolve.invoke(obj, new Object [0]); 253 } catch (InvocationTargetException e) { 254 if (e.getTargetException() != null) 255 throw e; 256 } 257 258 return obj; 259 } 260 261 protected Object instantiate() 262 throws Exception 263 { 264 if (_constructor != null) 265 return _constructor.newInstance(_constructorArgs); 266 else 267 return _type.newInstance(); 268 } 269 270 273 protected HashMap getFieldMap(Class cl) 274 { 275 HashMap fieldMap = new HashMap (); 276 277 for (; cl != null; cl = cl.getSuperclass()) { 278 Field []fields = cl.getDeclaredFields(); 279 for (int i = 0; i < fields.length; i++) { 280 Field field = fields[i]; 281 282 if (Modifier.isTransient(field.getModifiers()) || 283 Modifier.isStatic(field.getModifiers())) 284 continue; 285 else if (fieldMap.get(field.getName()) != null) 286 continue; 287 288 try { 290 field.setAccessible(true); 291 } catch (Throwable e) { 292 e.printStackTrace(); 293 } 294 295 Class type = field.getType(); 296 FieldDeserializer deser; 297 298 if (String .class.equals(type)) 299 deser = new StringFieldDeserializer(field); 300 else if (byte.class.equals(type)) { 301 deser = new ByteFieldDeserializer(field); 302 } 303 else if (short.class.equals(type)) { 304 deser = new ShortFieldDeserializer(field); 305 } 306 else if (int.class.equals(type)) { 307 deser = new IntFieldDeserializer(field); 308 } 309 else if (long.class.equals(type)) { 310 deser = new LongFieldDeserializer(field); 311 } 312 else if (float.class.equals(type)) { 313 deser = new FloatFieldDeserializer(field); 314 } 315 else if (double.class.equals(type)) { 316 deser = new DoubleFieldDeserializer(field); 317 } 318 else if (boolean.class.equals(type)) { 319 deser = new BooleanFieldDeserializer(field); 320 } 321 else { 322 deser = new ObjectFieldDeserializer(field); 323 } 324 325 fieldMap.put(field.getName(), deser); 326 } 327 } 328 329 return fieldMap; 330 } 331 332 335 protected static Object getParamArg(Class cl) 336 { 337 if (! cl.isPrimitive()) 338 return null; 339 else if (boolean.class.equals(cl)) 340 return Boolean.FALSE; 341 else if (byte.class.equals(cl)) 342 return new Byte ((byte) 0); 343 else if (short.class.equals(cl)) 344 return new Short ((short) 0); 345 else if (char.class.equals(cl)) 346 return new Character ((char) 0); 347 else if (int.class.equals(cl)) 348 return new Integer (0); 349 else if (long.class.equals(cl)) 350 return new Long (0); 351 else if (float.class.equals(cl)) 352 return new Float (0); 353 else if (double.class.equals(cl)) 354 return new Double (0); 355 else 356 throw new UnsupportedOperationException (); 357 } 358 359 abstract static class FieldDeserializer { 360 abstract void deserialize(AbstractHessianInput in, Object obj) 361 throws IOException ; 362 } 363 364 static class ObjectFieldDeserializer extends FieldDeserializer { 365 private final Field _field; 366 367 ObjectFieldDeserializer(Field field) 368 { 369 _field = field; 370 } 371 372 void deserialize(AbstractHessianInput in, Object obj) 373 throws IOException 374 { 375 Object value = in.readObject(_field.getType()); 376 377 try { 378 _field.set(obj, value); 379 } catch (IllegalAccessException e) { 380 } 382 } 383 } 384 385 static class BooleanFieldDeserializer extends FieldDeserializer { 386 private final Field _field; 387 388 BooleanFieldDeserializer(Field field) 389 { 390 _field = field; 391 } 392 393 void deserialize(AbstractHessianInput in, Object obj) 394 throws IOException 395 { 396 boolean value = in.readBoolean(); 397 398 try { 399 _field.setBoolean(obj, value); 400 } catch (IllegalAccessException e) { 401 } 403 } 404 } 405 406 static class ByteFieldDeserializer extends FieldDeserializer { 407 private final Field _field; 408 409 ByteFieldDeserializer(Field field) 410 { 411 _field = field; 412 } 413 414 void deserialize(AbstractHessianInput in, Object obj) 415 throws IOException 416 { 417 int value = in.readInt(); 418 419 try { 420 _field.setByte(obj, (byte) value); 421 } catch (IllegalAccessException e) { 422 } 424 } 425 } 426 427 static class ShortFieldDeserializer extends FieldDeserializer { 428 private final Field _field; 429 430 ShortFieldDeserializer(Field field) 431 { 432 _field = field; 433 } 434 435 void deserialize(AbstractHessianInput in, Object obj) 436 throws IOException 437 { 438 int value = in.readInt(); 439 440 try { 441 _field.setShort(obj, (short) value); 442 } catch (IllegalAccessException e) { 443 } 445 } 446 } 447 448 static class IntFieldDeserializer extends FieldDeserializer { 449 private final Field _field; 450 451 IntFieldDeserializer(Field field) 452 { 453 _field = field; 454 } 455 456 void deserialize(AbstractHessianInput in, Object obj) 457 throws IOException 458 { 459 int value = in.readInt(); 460 461 try { 462 _field.setInt(obj, value); 463 } catch (IllegalAccessException e) { 464 } 466 } 467 } 468 469 static class LongFieldDeserializer extends FieldDeserializer { 470 private final Field _field; 471 472 LongFieldDeserializer(Field field) 473 { 474 _field = field; 475 } 476 477 void deserialize(AbstractHessianInput in, Object obj) 478 throws IOException 479 { 480 long value = in.readLong(); 481 482 try { 483 _field.setLong(obj, value); 484 } catch (IllegalAccessException e) { 485 } 487 } 488 } 489 490 static class FloatFieldDeserializer extends FieldDeserializer { 491 private final Field _field; 492 493 FloatFieldDeserializer(Field field) 494 { 495 _field = field; 496 } 497 498 void deserialize(AbstractHessianInput in, Object obj) 499 throws IOException 500 { 501 double value = in.readDouble(); 502 503 try { 504 _field.setFloat(obj, (float) value); 505 } catch (IllegalAccessException e) { 506 } 508 } 509 } 510 511 static class DoubleFieldDeserializer extends FieldDeserializer { 512 private final Field _field; 513 514 DoubleFieldDeserializer(Field field) 515 { 516 _field = field; 517 } 518 519 void deserialize(AbstractHessianInput in, Object obj) 520 throws IOException 521 { 522 double value = in.readDouble(); 523 524 try { 525 _field.setDouble(obj, value); 526 } catch (IllegalAccessException e) { 527 } 529 } 530 } 531 532 static class StringFieldDeserializer extends FieldDeserializer { 533 private final Field _field; 534 535 StringFieldDeserializer(Field field) 536 { 537 _field = field; 538 } 539 540 void deserialize(AbstractHessianInput in, Object obj) 541 throws IOException 542 { 543 String value = in.readString(); 544 545 try { 546 _field.set(obj, value); 547 } catch (IllegalAccessException e) { 548 } 550 } 551 } 552 } 553
| Popular Tags
|