1 18 package org.apache.geronimo.interop.rmi.iiop; 19 20 import org.apache.geronimo.interop.*; 21 import org.apache.geronimo.interop.util.*; 22 import java.io.*; 23 import java.lang.reflect.*; 24 import java.util.*; 25 26 public class ObjectOutputStream extends java.io.ObjectOutputStream 27 { 28 29 public static ObjectOutputStream getInstance() 30 { 31 ObjectOutputStream oos = null; 32 try { 33 oos = new ObjectOutputStream(); 34 } catch (IOException e) { 35 e.printStackTrace(); oos = null; 37 } 38 return oos; 39 } 40 41 public static ObjectOutputStream getInstance(CdrOutputStream cdrOutput) 42 { 43 ObjectOutputStream output = getInstance(); 44 output.init(cdrOutput); 45 return output; 46 } 47 48 public static ObjectOutputStream getPooledInstance() 49 { 50 ObjectOutputStream output = null; 51 if (output == null) 52 { 53 output = getInstance(); 54 } 55 return output; 56 } 57 58 62 protected static class StreamState 63 { 64 ValueType type; 65 Object value; 66 int offset; 67 org.apache.geronimo.interop.rmi.iiop.ObjectOutputStream.PutField putField; 68 69 StreamState(ValueType type, Object value, int offset) 70 { 71 this.type = type; 72 this.value = value; 73 this.offset = offset; 74 } 75 } 76 77 81 public CdrOutputStream _cdrOutput; 82 83 public boolean _hasException; 84 85 public Object [] thisAsObjectArray; 86 87 91 private static ValueType OBJECT_VALUE_TYPE = ValueType.getInstance(java.lang.Object .class); 92 93 private static boolean OBJECT_VALUE_TYPE_INIT = false; 94 95 private ArrayList _stack = null; 96 97 private SimpleIdentityHashMap _indirection; 98 99 private int _blockSizeIndex = -1; 100 101 private int _endLevel; 102 103 private int _endTagIndex; 104 105 private boolean _inBlock = false; 106 107 private boolean _isChunked = false; 108 109 private int _booleanIndex = -1; 110 111 115 public ObjectOutputStream() throws IOException 116 { 117 super(); 118 } 119 120 public void $reset() 121 { 122 _cdrOutput.reset(); 123 if (_indirection != null) 124 { 125 _indirection.clear(); 126 } 127 if (_stack != null) 128 { 129 _stack.clear(); 130 } 131 _blockSizeIndex = -1; 132 _endLevel = 0; 133 _endTagIndex = 0; 134 _inBlock = false; 135 _isChunked = false; 136 _booleanIndex = -1; 137 } 138 139 public void recycle() 140 { 141 $reset(); 142 } 143 144 148 public void writeBoolean(boolean value) 149 { 150 _cdrOutput.write_boolean(value); 151 } 152 153 public void writeChar(char value) 154 { 155 _cdrOutput.write_wchar(value); 156 } 157 158 public void writeByte(byte value) 159 { 160 _cdrOutput.write_octet(value); 161 } 162 163 public void writeShort(short value) 164 { 165 _cdrOutput.write_short(value); 166 } 167 168 public void writeInt(int value) 169 { 170 _cdrOutput.write_long(value); 171 } 172 173 public void writeLong(long value) 174 { 175 _cdrOutput.write_longlong(value); 176 } 177 178 public void writeFloat(float value) 179 { 180 _cdrOutput.write_float(value); 181 } 182 183 public void writeDouble(double value) 184 { 185 _cdrOutput.write_double(value); 186 } 187 188 public void writeObjectOverride(Object value) 189 { 190 writeObject(OBJECT_VALUE_TYPE, value, true); 191 } 192 193 public void defaultWriteObject() throws IOException 194 { 195 StreamState state = top(); 196 int saveOffset = _cdrOutput._offset; 198 _cdrOutput._offset = _booleanIndex; 199 _cdrOutput.write_boolean(true); 200 _cdrOutput._offset = saveOffset; 201 writeDeclaredFields(state.type, state.value); 202 } 203 204 208 public boolean hasException() 209 { 210 return _hasException; 211 } 212 213 public void writeException(ValueType type, Exception value) 214 { 215 String className = type._class.getName(); 216 String exType = StringUtil.removeSuffix(className, "Exception") + "Ex"; 217 String repositoryID = "IDL:" + exType.replace('.', '/') + ":1.0"; 218 _cdrOutput.write_string(repositoryID); 219 writeObject(type, value); 220 _hasException = true; 221 } 222 223 public void writeObject(ValueType type, Object value) 224 { 225 writeObject(type, value, false); 226 } 227 228 232 protected void init(CdrOutputStream cdrOutput) 233 { 234 _cdrOutput = cdrOutput; 235 thisAsObjectArray = new Object [] { this }; 236 } 237 238 protected void putIndirection(Object value, Integer ref) 239 { 240 if (_indirection == null) 241 { 242 _indirection = new SimpleIdentityHashMap(8); 243 } 244 _indirection.put(value, ref); 245 } 246 247 protected void writeObject(ValueType declaredType, Object value, boolean calledFromCustomSerialization) 248 { 249 ValueType actualType = declaredType; 250 while (value != null) 251 { 252 Class vc = value.getClass(); 253 if (vc != declaredType._class) 254 { 255 actualType = ValueType.getInstance(vc); 256 } 257 if (actualType.hasWriteReplace) 258 { 259 value = actualType.writeReplace(value); 260 } 261 else 262 { 263 break; 264 } 265 } 266 boolean saveIsChunked = _isChunked; 267 if (_inBlock) 268 { 269 if (actualType != null) 270 { 271 if (!declaredType.isAny || calledFromCustomSerialization) 272 { 273 endBlock(); 274 } 275 } 276 } 277 if (value == null) 278 { 279 if (calledFromCustomSerialization) 280 { 281 _cdrOutput.write_boolean(actualType.isObjectRef); 282 if(actualType.isObjectRef) 283 { 284 writeObjectRef(value); 285 endBlock(); 286 } 287 else 288 { 289 _cdrOutput.write_long(ValueType.NULL_VALUE_TAG); 290 } 291 return; 292 } 293 if (declaredType.isAny) 294 { 295 _cdrOutput.write_TypeCode(ValueType.TC_ABSTRACT_BASE); 296 _cdrOutput.write_boolean(false); 297 } 298 if (declaredType.isObjectRef) 299 { 300 writeObjectRef(value); 301 } 302 else 303 { 304 if (declaredType.isAbstractInterface) 305 { 306 _cdrOutput.write_boolean(false); 307 } 308 _cdrOutput.write_long(ValueType.NULL_VALUE_TAG); 309 } 310 return; 311 } 312 if (declaredType.isAny && ! calledFromCustomSerialization) 313 { 314 org.omg.CORBA.TypeCode tc = actualType.tc; 315 _cdrOutput.write_TypeCode(tc); 316 if (!actualType.isAny) 317 { 318 endBlock(); 319 } 320 } 321 else if (declaredType.isAbstractInterface || calledFromCustomSerialization) 322 { 323 _cdrOutput.write_boolean(actualType.isObjectRef); 324 if (actualType.isObjectRef) 325 { 326 writeObjectRef(value); 327 return; 328 } 329 } 330 if (actualType.isObjectRef) 331 { 332 writeObjectRef(value); 333 return; 334 } 335 Integer ref = _indirection == null ? null : (Integer )_indirection.get(value); 336 if (ref != null) 337 { 338 _cdrOutput.write_long(ValueType.INDIRECTION_TAG); 339 _cdrOutput.write_long(ref.intValue() - _cdrOutput._offset); 340 return; 341 } 342 else 343 { 344 _cdrOutput.write_align(4, 4); ref = IntegerCache.get(_cdrOutput._offset); 346 putIndirection(value, ref); 347 } 348 if (saveIsChunked || actualType.requiresCustomSerialization) 349 { 350 _cdrOutput.write_long(ValueType.TRUNCATABLE_SINGLE_TYPE_VALUE_TAG); 351 _isChunked = true; 352 } 353 else 354 { 355 _cdrOutput.write_long(ValueType.SINGLE_TYPE_VALUE_TAG); 356 _isChunked = false; 357 } 358 359 writeMetaString(actualType.id); 360 startBlock(); 361 switch (actualType.readWriteCase) 362 { 363 case ValueType.CASE_ARRAY: 364 writeArray(actualType, value); 365 break; 366 case ValueType.CASE_CLASS: 367 writeClassDesc((java.lang.Class )value); 368 break; 369 case ValueType.CASE_IDL_ENTITY: 370 actualType.helper.write(this, value); 371 break; 372 case ValueType.CASE_STRING: 374 _cdrOutput.write_wstring((String )value); 375 break; 376 default: 377 writeObjectState(actualType, value); 378 } 379 endBlock(); 380 writeEndTag(declaredType, actualType, calledFromCustomSerialization); 381 _isChunked = saveIsChunked; 382 } 383 384 protected void writeMetaString(String ms) 385 { 386 Integer ref = (Integer )_indirection.get(ms); 387 if (ref != null) 388 { 389 _cdrOutput.write_long(ValueType.INDIRECTION_TAG); 390 _cdrOutput.write_long(ref.intValue() - _cdrOutput._offset); 391 } 392 else 393 { 394 ref = IntegerCache.get(_cdrOutput._offset); 395 _cdrOutput.write_string(ms); 396 putIndirection(ms, ref); 397 } 398 } 399 400 protected void writeObjectState(ValueType type, Object value) 401 { 402 if (type.isExternalizable) 403 { 404 _cdrOutput.write_octet((byte)1); 405 type.writeExternal(value, this); 406 return; 407 } 408 if (type.hasParentState) 409 { 410 writeObjectState(type.parent, value); 411 } 412 if (type.hasWriteObject) 413 { 414 push(new StreamState(type, value, _cdrOutput._offset)); 415 if (type.skipCustomFlags) 416 { 417 _booleanIndex = _cdrOutput._offset; 418 } 419 else 420 { 421 _cdrOutput.write_octet((byte)1); 422 _cdrOutput.write_boolean(false); 423 _booleanIndex = _cdrOutput._offset - 1; 424 } 425 type.writeObject(value, this); 426 pop(); 427 } 428 else 429 { 430 writeDeclaredFields(type, value); 431 } 432 } 433 434 protected void writeDeclaredFields(ValueType type, Object value) 435 { 436 int n = type.fields.length; 437 for (int f = 0; f < n; f++) 438 { 439 ValueTypeField field = type.fields[f]; 440 int primitive = field.primitive; 441 if (primitive != 0) 442 { 443 writePrimitive(primitive, field, value); 444 } 445 else 446 { 447 writeObject(field.type, field.get(value), false); 448 } 449 } 450 } 451 452 protected void writeClassDesc(Class theClass) 453 { 454 writeObject(ValueType.STRING_VALUE_TYPE, null); writeObject(ValueType.STRING_VALUE_TYPE, ValueType.getInstance(theClass).id); 456 } 457 458 protected void writeArray(ValueType arrayType, Object value) 459 { 460 int primitive = arrayType.primitiveArray; 461 if (primitive != 0) 462 { 463 arrayType.helper.write(this, value); 464 } 465 else 466 { 467 Object [] array = (Object [])value; 468 int n = array.length; 469 _cdrOutput.write_ulong(n); 470 for (int i = 0; i < n; i++) 471 { 472 writeObject(arrayType.element, array[i], false); 473 } 474 } 475 } 476 477 protected void writePrimitive(int primitive, ValueTypeField field, Object value) 478 { 479 switch (primitive) 480 { 481 case PrimitiveType.BOOLEAN: 482 _cdrOutput.write_boolean(field.getBoolean(value)); 483 break; 484 case PrimitiveType.BYTE: 485 _cdrOutput.write_octet(field.getByte(value)); 486 break; 487 case PrimitiveType.CHAR: 488 _cdrOutput.write_wchar(field.getChar(value)); 489 break; 490 case PrimitiveType.DOUBLE: 491 _cdrOutput.write_double(field.getDouble(value)); 492 break; 493 case PrimitiveType.FLOAT: 494 _cdrOutput.write_float(field.getFloat(value)); 495 break; 496 case PrimitiveType.INT: 497 _cdrOutput.write_long(field.getInt(value)); 498 break; 499 case PrimitiveType.LONG: 500 _cdrOutput.write_longlong(field.getLong(value)); 501 break; 502 case PrimitiveType.SHORT: 503 _cdrOutput.write_short(field.getShort(value)); 504 break; 505 default: 506 throw new IllegalStateException (); 507 } 508 } 509 510 public void startBlock() 511 { 512 if (! _isChunked) 513 { 514 return; 515 } 516 _endLevel--; 517 _cdrOutput.write_long(0); 518 _inBlock = true; 519 _blockSizeIndex = _cdrOutput._offset - 4; 520 } 521 522 public void endBlock() 523 { 524 if (! _inBlock) 525 { 526 return; 527 } 528 _inBlock = false; 529 int oldSize = _cdrOutput._offset; 530 _cdrOutput._offset = _blockSizeIndex; 531 _cdrOutput.write_long(oldSize - _blockSizeIndex - 4); 532 _cdrOutput._offset = oldSize; 533 _blockSizeIndex = -1; 534 } 535 536 protected void writeEndTag() 537 { 538 if (_isChunked) 539 { 540 if (_endTagIndex == _cdrOutput._offset - 8) 541 { 542 _cdrOutput._offset -= 8; 543 } 544 _cdrOutput.write_long(_endLevel); 545 _endTagIndex = _cdrOutput._offset - 4; 546 if (_endLevel != -1) 547 { 548 _cdrOutput.write_long(1); 549 } 550 else { 552 _cdrOutput._offset -=4; 553 _cdrOutput.write_long(-1); 554 _isChunked = false; 555 } 556 _endLevel++; 557 } 558 } 559 560 protected void writeEndTag(ValueType declaredType, ValueType actualType, 561 boolean calledFromCustomSerialization) 562 { 563 if (_isChunked) 564 { 565 if (_endTagIndex == _cdrOutput._offset - 8) 566 { 567 _cdrOutput._offset -= 8; 568 } 569 _cdrOutput.write_long(_endLevel); 570 _endTagIndex = _cdrOutput._offset - 4; 571 if (_endLevel != -1) 572 { 573 if(declaredType.isAny && !actualType.isAny && !calledFromCustomSerialization) 574 { 575 startBlock(); 576 _endLevel++; 577 } 578 else 579 { 580 _cdrOutput.write_long(1); 581 } 582 } 583 else { 585 _cdrOutput._offset -=4; 586 _cdrOutput.write_long(-1); 587 _isChunked = false; 588 } 589 _endLevel++; 590 } 591 } 592 593 private void writeObjectRef(java.lang.Object value) 594 { 595 if(value instanceof org.apache.geronimo.interop.rmi.iiop.ObjectRef || value == null) 596 { 597 _cdrOutput.write_Object((org.omg.CORBA.Object )value); 598 } 599 else if (value instanceof RemoteInterface) 600 { 601 ObjectRef objectRef = ((RemoteInterface)value).getObjectRef(); 602 value = objectRef; 603 _cdrOutput.write_Object((org.omg.CORBA.Object )value); 604 } 605 else 606 { 607 writeForeignObjectRef(value); 608 } 609 } 610 611 private void writeForeignObjectRef(java.lang.Object value) 612 { 613 if (value instanceof java.rmi.Remote ) 614 { 615 try 616 { 617 value = (org.omg.CORBA.Object )javax.rmi.PortableRemoteObject.toStub((java.rmi.Remote )value); 618 } 619 catch (java.rmi.NoSuchObjectException ex) 620 { 621 throw new org.omg.CORBA.MARSHAL (ExceptionUtil.causedBy(ex)); 622 } 623 } 624 625 if (value instanceof org.omg.CORBA.Object ) 626 { 627 try 628 { 629 org.omg.CORBA.Object object = (org.omg.CORBA.Object )value; 630 org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(new String [0], null); 631 orb.create_output_stream().write_Object(object); 632 String ior = orb.object_to_string(object); 633 org.apache.geronimo.interop.rmi.iiop.ObjectRef objectRef = org.apache.geronimo.interop.rmi.iiop.ObjectRef.$getObjectFromIOR(ior); 634 _cdrOutput.write_Object((org.omg.CORBA.Object )objectRef); 635 } 636 catch (Exception ex) 637 { 638 throw new org.omg.CORBA.MARSHAL (ExceptionUtil.causedBy(ex)); 639 } 640 } 641 else 642 { 643 throw new org.omg.CORBA.MARSHAL ("writeObjectRef: " + value.getClass().getName()); 644 } 645 } 646 647 public java.io.ObjectOutputStream.PutField putFields() throws IOException 648 { 649 StreamState state = top(); 650 651 Class currentClass = state.type.getTheClass(); 652 if(currentClass == null) 653 { 654 throw new IOException("putFields: class from ValueType is null"); 655 } 656 657 java.io.ObjectStreamClass osc = ObjectStreamClass.lookup(currentClass); 658 if(osc == null) 659 { 660 throw new IOException("putFields: ObjectSteamClass is null"); 661 } 662 663 org.apache.geronimo.interop.rmi.iiop.PutField pf = new org.apache.geronimo.interop.rmi.iiop.PutField(osc); 664 state.putField = pf; 665 return pf; 666 } 667 668 public void writeFields() throws IOException 669 { 670 StreamState state = top(); 671 if(state.putField == null) 672 { 673 throw new IOException("writeFields: PutField object is null"); 674 } 675 676 org.apache.geronimo.interop.rmi.iiop.PutField pf = (org.apache.geronimo.interop.rmi.iiop.PutField)state.putField; 677 pf.writeFields(this); 678 } 679 680 protected void push(StreamState state) 681 { 682 if (_stack == null) 683 { 684 _stack = new ArrayList(); 685 } 686 _stack.add(state); 687 } 688 689 protected void pop() 690 { 691 int n = _stack.size(); 692 if (n == 0) 693 { 694 throw new SystemException("pop: state stack empty"); 695 } 696 _stack.remove(n - 1); 697 } 698 699 private StreamState top() 700 { 701 int n = _stack.size(); 702 if (n == 0) 703 { 704 throw new SystemException("top: state stack empty"); 705 } 706 return (StreamState)_stack.get(n - 1); 707 } 708 } 709 | Popular Tags |