src/share/classes/com/sun/corba/se/impl/io/IIOPOutputStream.java

Thu, 31 Aug 2017 18:10:36 +0800

author
aoqi
date
Thu, 31 Aug 2017 18:10:36 +0800
changeset 748
6845b95cba6b
parent 478
80161c61aa68
parent 0
7ef37b2cdcad
child 1410
9c913ea7e4a1
permissions
-rw-r--r--

merge

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation. Oracle designates this
aoqi@0 8 * particular file as subject to the "Classpath" exception as provided
aoqi@0 9 * by Oracle in the LICENSE file that accompanied this code.
aoqi@0 10 *
aoqi@0 11 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 14 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 15 * accompanied this code).
aoqi@0 16 *
aoqi@0 17 * You should have received a copy of the GNU General Public License version
aoqi@0 18 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 20 *
aoqi@0 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 22 * or visit www.oracle.com if you need additional information or have any
aoqi@0 23 * questions.
aoqi@0 24 */
aoqi@0 25 /*
aoqi@0 26 * Licensed Materials - Property of IBM
aoqi@0 27 * RMI-IIOP v1.0
aoqi@0 28 * Copyright IBM Corp. 1998 1999 All Rights Reserved
aoqi@0 29 *
aoqi@0 30 */
aoqi@0 31
aoqi@0 32 package com.sun.corba.se.impl.io;
aoqi@0 33
aoqi@0 34 import org.omg.CORBA.INTERNAL;
aoqi@0 35 import org.omg.CORBA.portable.OutputStream;
aoqi@0 36
aoqi@0 37 import java.security.AccessController ;
aoqi@0 38 import java.security.PrivilegedAction ;
aoqi@0 39
aoqi@0 40 import java.io.IOException;
aoqi@0 41 import java.io.DataOutputStream;
aoqi@0 42 import java.io.Serializable;
aoqi@0 43 import java.io.InvalidClassException;
aoqi@0 44 import java.io.StreamCorruptedException;
aoqi@0 45 import java.io.Externalizable;
aoqi@0 46 import java.io.ObjectStreamException;
aoqi@0 47 import java.io.NotSerializableException;
aoqi@0 48 import java.io.NotActiveException;
aoqi@0 49
aoqi@0 50 import java.lang.reflect.InvocationTargetException;
aoqi@0 51 import java.lang.reflect.Field;
aoqi@0 52
aoqi@0 53 import java.util.Stack;
aoqi@0 54
aoqi@0 55 import javax.rmi.CORBA.Util;
aoqi@0 56 import javax.rmi.CORBA.ValueHandlerMultiFormat;
aoqi@0 57
aoqi@0 58 import sun.corba.Bridge ;
aoqi@0 59
aoqi@0 60 import com.sun.corba.se.impl.io.ObjectStreamClass;
aoqi@0 61 import com.sun.corba.se.impl.util.Utility;
aoqi@0 62 import com.sun.corba.se.impl.util.RepositoryId;
aoqi@0 63
aoqi@0 64 import com.sun.corba.se.spi.logging.CORBALogDomains ;
aoqi@0 65 import com.sun.corba.se.impl.logging.UtilSystemException ;
aoqi@0 66
aoqi@0 67 /**
aoqi@0 68 * IIOPOutputStream is ...
aoqi@0 69 *
aoqi@0 70 * @author Stephen Lewallen
aoqi@0 71 * @since JDK1.1.6
aoqi@0 72 */
aoqi@0 73
aoqi@0 74 public class IIOPOutputStream
aoqi@0 75 extends com.sun.corba.se.impl.io.OutputStreamHook
aoqi@0 76 {
aoqi@0 77 private UtilSystemException wrapper = UtilSystemException.get(
aoqi@0 78 CORBALogDomains.RPC_ENCODING ) ;
aoqi@0 79
aoqi@0 80 private static Bridge bridge =
aoqi@0 81 (Bridge)AccessController.doPrivileged(
aoqi@0 82 new PrivilegedAction() {
aoqi@0 83 public Object run() {
aoqi@0 84 return Bridge.get() ;
aoqi@0 85 }
aoqi@0 86 }
aoqi@0 87 ) ;
aoqi@0 88
aoqi@0 89 private org.omg.CORBA_2_3.portable.OutputStream orbStream;
aoqi@0 90
aoqi@0 91 private Object currentObject = null;
aoqi@0 92
aoqi@0 93 private ObjectStreamClass currentClassDesc = null;
aoqi@0 94
aoqi@0 95 private int recursionDepth = 0;
aoqi@0 96
aoqi@0 97 private int simpleWriteDepth = 0;
aoqi@0 98
aoqi@0 99 private IOException abortIOException = null;
aoqi@0 100
aoqi@0 101 private java.util.Stack classDescStack = new java.util.Stack();
aoqi@0 102
aoqi@0 103 // Used when calling an object's writeObject method
aoqi@0 104 private Object[] writeObjectArgList = {this};
aoqi@0 105
aoqi@0 106 public IIOPOutputStream()
aoqi@0 107 throws java.io.IOException
aoqi@0 108 {
aoqi@0 109 super();
aoqi@0 110 }
aoqi@0 111
aoqi@0 112 // If using RMI-IIOP stream format version 2, this tells
aoqi@0 113 // the ORB stream (which must be a ValueOutputStream) to
aoqi@0 114 // begin a new valuetype to contain the optional data
aoqi@0 115 // of the writeObject method.
aoqi@0 116 protected void beginOptionalCustomData() {
aoqi@0 117
aoqi@0 118 if (streamFormatVersion == 2) {
aoqi@0 119
aoqi@0 120 org.omg.CORBA.portable.ValueOutputStream vout
aoqi@0 121 = (org.omg.CORBA.portable.ValueOutputStream)orbStream;
aoqi@0 122
aoqi@0 123 vout.start_value(currentClassDesc.getRMIIIOPOptionalDataRepId());
aoqi@0 124 }
aoqi@0 125 }
aoqi@0 126
aoqi@0 127 final void setOrbStream(org.omg.CORBA_2_3.portable.OutputStream os) {
aoqi@0 128 orbStream = os;
aoqi@0 129 }
aoqi@0 130
aoqi@0 131 final org.omg.CORBA_2_3.portable.OutputStream getOrbStream() {
aoqi@0 132 return orbStream;
aoqi@0 133 }
aoqi@0 134
aoqi@0 135 final void increaseRecursionDepth(){
aoqi@0 136 recursionDepth++;
aoqi@0 137 }
aoqi@0 138
aoqi@0 139 final int decreaseRecursionDepth(){
aoqi@0 140 return --recursionDepth;
aoqi@0 141 }
aoqi@0 142
aoqi@0 143 /**
aoqi@0 144 * Override the actions of the final method "writeObject()"
aoqi@0 145 * in ObjectOutputStream.
aoqi@0 146 * @since JDK1.1.6
aoqi@0 147 */
aoqi@0 148 public final void writeObjectOverride(Object obj)
aoqi@0 149 throws IOException
aoqi@0 150 {
aoqi@0 151 writeObjectState.writeData(this);
aoqi@0 152
aoqi@0 153 Util.writeAbstractObject((OutputStream)orbStream, obj);
aoqi@0 154 }
aoqi@0 155
aoqi@0 156 /**
aoqi@0 157 * Override the actions of the final method "writeObject()"
aoqi@0 158 * in ObjectOutputStream.
aoqi@0 159 * @since JDK1.1.6
aoqi@0 160 */
aoqi@0 161 public final void simpleWriteObject(Object obj, byte formatVersion)
aoqi@0 162 /* throws IOException */
aoqi@0 163 {
aoqi@0 164 byte oldStreamFormatVersion = streamFormatVersion;
aoqi@0 165
aoqi@0 166 streamFormatVersion = formatVersion;
aoqi@0 167
aoqi@0 168 Object prevObject = currentObject;
aoqi@0 169 ObjectStreamClass prevClassDesc = currentClassDesc;
aoqi@0 170 simpleWriteDepth++;
aoqi@0 171
aoqi@0 172 try {
aoqi@0 173 // if (!checkSpecialClasses(obj) && !checkSubstitutableSpecialClasses(obj))
aoqi@0 174 outputObject(obj);
aoqi@0 175
aoqi@0 176 } catch (IOException ee) {
aoqi@0 177 if (abortIOException == null)
aoqi@0 178 abortIOException = ee;
aoqi@0 179 } finally {
aoqi@0 180 /* Restore state of previous call incase this is a nested call */
aoqi@0 181 streamFormatVersion = oldStreamFormatVersion;
aoqi@0 182 simpleWriteDepth--;
aoqi@0 183 currentObject = prevObject;
aoqi@0 184 currentClassDesc = prevClassDesc;
aoqi@0 185 }
aoqi@0 186
aoqi@0 187 /* If the recursion depth is 0, test for and clear the pending exception.
aoqi@0 188 * If there is a pending exception throw it.
aoqi@0 189 */
aoqi@0 190 IOException pending = abortIOException;
aoqi@0 191 if (simpleWriteDepth == 0)
aoqi@0 192 abortIOException = null;
aoqi@0 193 if (pending != null) {
aoqi@0 194 bridge.throwException( pending ) ;
aoqi@0 195 }
aoqi@0 196 }
aoqi@0 197
aoqi@0 198 // Required by the superclass.
aoqi@0 199 ObjectStreamField[] getFieldsNoCopy() {
aoqi@0 200 return currentClassDesc.getFieldsNoCopy();
aoqi@0 201 }
aoqi@0 202
aoqi@0 203 /**
aoqi@0 204 * Override the actions of the final method "defaultWriteObject()"
aoqi@0 205 * in ObjectOutputStream.
aoqi@0 206 * @since JDK1.1.6
aoqi@0 207 */
aoqi@0 208 public final void defaultWriteObjectDelegate()
aoqi@0 209 /* throws IOException */
aoqi@0 210 {
aoqi@0 211 try {
aoqi@0 212 if (currentObject == null || currentClassDesc == null)
aoqi@0 213 // XXX I18N, Logging needed.
aoqi@0 214 throw new NotActiveException("defaultWriteObjectDelegate");
aoqi@0 215
aoqi@0 216 ObjectStreamField[] fields =
aoqi@0 217 currentClassDesc.getFieldsNoCopy();
aoqi@0 218 if (fields.length > 0) {
aoqi@0 219 outputClassFields(currentObject, currentClassDesc.forClass(),
aoqi@0 220 fields);
aoqi@0 221 }
aoqi@0 222 } catch(IOException ioe) {
aoqi@0 223 bridge.throwException(ioe);
aoqi@0 224 }
aoqi@0 225 }
aoqi@0 226
aoqi@0 227 /**
aoqi@0 228 * Override the actions of the final method "enableReplaceObject()"
aoqi@0 229 * in ObjectOutputStream.
aoqi@0 230 * @since JDK1.1.6
aoqi@0 231 */
aoqi@0 232 public final boolean enableReplaceObjectDelegate(boolean enable)
aoqi@0 233 /* throws SecurityException */
aoqi@0 234 {
aoqi@0 235 return false;
aoqi@0 236
aoqi@0 237 }
aoqi@0 238
aoqi@0 239
aoqi@0 240 protected final void annotateClass(Class<?> cl) throws IOException{
aoqi@0 241 // XXX I18N, Logging needed.
aoqi@0 242 throw new IOException("Method annotateClass not supported");
aoqi@0 243 }
aoqi@0 244
aoqi@0 245 public final void close() throws IOException{
aoqi@0 246 // no op
aoqi@0 247 }
aoqi@0 248
aoqi@0 249 protected final void drain() throws IOException{
aoqi@0 250 // no op
aoqi@0 251 }
aoqi@0 252
aoqi@0 253 public final void flush() throws IOException{
aoqi@0 254 try{
aoqi@0 255 orbStream.flush();
aoqi@0 256 } catch(Error e) {
aoqi@0 257 IOException ioexc = new IOException(e.getMessage());
aoqi@0 258 ioexc.initCause(e) ;
aoqi@0 259 throw ioexc ;
aoqi@0 260 }
aoqi@0 261 }
aoqi@0 262
aoqi@0 263 protected final Object replaceObject(Object obj) throws IOException{
aoqi@0 264 // XXX I18N, Logging needed.
aoqi@0 265 throw new IOException("Method replaceObject not supported");
aoqi@0 266 }
aoqi@0 267
aoqi@0 268 /**
aoqi@0 269 * Reset will disregard the state of any objects already written
aoqi@0 270 * to the stream. The state is reset to be the same as a new
aoqi@0 271 * ObjectOutputStream. The current point in the stream is marked
aoqi@0 272 * as reset so the corresponding ObjectInputStream will be reset
aoqi@0 273 * at the same point. Objects previously written to the stream
aoqi@0 274 * will not be refered to as already being in the stream. They
aoqi@0 275 * will be written to the stream again.
aoqi@0 276 * @since JDK1.1
aoqi@0 277 */
aoqi@0 278 public final void reset() throws IOException{
aoqi@0 279 try{
aoqi@0 280 //orbStream.reset();
aoqi@0 281
aoqi@0 282 if (currentObject != null || currentClassDesc != null)
aoqi@0 283 // XXX I18N, Logging needed.
aoqi@0 284 throw new IOException("Illegal call to reset");
aoqi@0 285
aoqi@0 286 abortIOException = null;
aoqi@0 287
aoqi@0 288 if (classDescStack == null)
aoqi@0 289 classDescStack = new java.util.Stack();
aoqi@0 290 else
aoqi@0 291 classDescStack.setSize(0);
aoqi@0 292
aoqi@0 293 } catch(Error e) {
aoqi@0 294 IOException ioexc = new IOException(e.getMessage());
aoqi@0 295 ioexc.initCause(e) ;
aoqi@0 296 throw ioexc ;
aoqi@0 297 }
aoqi@0 298 }
aoqi@0 299
aoqi@0 300 public final void write(byte b[]) throws IOException{
aoqi@0 301 try{
aoqi@0 302 writeObjectState.writeData(this);
aoqi@0 303
aoqi@0 304 orbStream.write_octet_array(b, 0, b.length);
aoqi@0 305 } catch(Error e) {
aoqi@0 306 IOException ioexc = new IOException(e.getMessage());
aoqi@0 307 ioexc.initCause(e) ;
aoqi@0 308 throw ioexc ;
aoqi@0 309 }
aoqi@0 310 }
aoqi@0 311
aoqi@0 312 public final void write(byte b[], int off, int len) throws IOException{
aoqi@0 313 try{
aoqi@0 314 writeObjectState.writeData(this);
aoqi@0 315
aoqi@0 316 orbStream.write_octet_array(b, off, len);
aoqi@0 317 } catch(Error e) {
aoqi@0 318 IOException ioexc = new IOException(e.getMessage());
aoqi@0 319 ioexc.initCause(e) ;
aoqi@0 320 throw ioexc ;
aoqi@0 321 }
aoqi@0 322 }
aoqi@0 323
aoqi@0 324 public final void write(int data) throws IOException{
aoqi@0 325 try{
aoqi@0 326 writeObjectState.writeData(this);
aoqi@0 327
aoqi@0 328 orbStream.write_octet((byte)(data & 0xFF));
aoqi@0 329 } catch(Error e) {
aoqi@0 330 IOException ioexc = new IOException(e.getMessage());
aoqi@0 331 ioexc.initCause(e) ;
aoqi@0 332 throw ioexc ;
aoqi@0 333 }
aoqi@0 334 }
aoqi@0 335
aoqi@0 336 public final void writeBoolean(boolean data) throws IOException{
aoqi@0 337 try{
aoqi@0 338 writeObjectState.writeData(this);
aoqi@0 339
aoqi@0 340 orbStream.write_boolean(data);
aoqi@0 341 } catch(Error e) {
aoqi@0 342 IOException ioexc = new IOException(e.getMessage());
aoqi@0 343 ioexc.initCause(e) ;
aoqi@0 344 throw ioexc ;
aoqi@0 345 }
aoqi@0 346 }
aoqi@0 347
aoqi@0 348 public final void writeByte(int data) throws IOException{
aoqi@0 349 try{
aoqi@0 350 writeObjectState.writeData(this);
aoqi@0 351
aoqi@0 352 orbStream.write_octet((byte)data);
aoqi@0 353 } catch(Error e) {
aoqi@0 354 IOException ioexc = new IOException(e.getMessage());
aoqi@0 355 ioexc.initCause(e) ;
aoqi@0 356 throw ioexc ;
aoqi@0 357 }
aoqi@0 358 }
aoqi@0 359
aoqi@0 360 public final void writeBytes(String data) throws IOException{
aoqi@0 361 try{
aoqi@0 362 writeObjectState.writeData(this);
aoqi@0 363
aoqi@0 364 byte buf[] = data.getBytes();
aoqi@0 365 orbStream.write_octet_array(buf, 0, buf.length);
aoqi@0 366 } catch(Error e) {
aoqi@0 367 IOException ioexc = new IOException(e.getMessage());
aoqi@0 368 ioexc.initCause(e) ;
aoqi@0 369 throw ioexc ;
aoqi@0 370 }
aoqi@0 371 }
aoqi@0 372
aoqi@0 373 public final void writeChar(int data) throws IOException{
aoqi@0 374 try{
aoqi@0 375 writeObjectState.writeData(this);
aoqi@0 376
aoqi@0 377 orbStream.write_wchar((char)data);
aoqi@0 378 } catch(Error e) {
aoqi@0 379 IOException ioexc = new IOException(e.getMessage());
aoqi@0 380 ioexc.initCause(e) ;
aoqi@0 381 throw ioexc ;
aoqi@0 382 }
aoqi@0 383 }
aoqi@0 384
aoqi@0 385 public final void writeChars(String data) throws IOException{
aoqi@0 386 try{
aoqi@0 387 writeObjectState.writeData(this);
aoqi@0 388
aoqi@0 389 char buf[] = data.toCharArray();
aoqi@0 390 orbStream.write_wchar_array(buf, 0, buf.length);
aoqi@0 391 } catch(Error e) {
aoqi@0 392 IOException ioexc = new IOException(e.getMessage());
aoqi@0 393 ioexc.initCause(e) ;
aoqi@0 394 throw ioexc ;
aoqi@0 395 }
aoqi@0 396 }
aoqi@0 397
aoqi@0 398 public final void writeDouble(double data) throws IOException{
aoqi@0 399 try{
aoqi@0 400 writeObjectState.writeData(this);
aoqi@0 401
aoqi@0 402 orbStream.write_double(data);
aoqi@0 403 } catch(Error e) {
aoqi@0 404 IOException ioexc = new IOException(e.getMessage());
aoqi@0 405 ioexc.initCause(e) ;
aoqi@0 406 throw ioexc ;
aoqi@0 407 }
aoqi@0 408 }
aoqi@0 409
aoqi@0 410 public final void writeFloat(float data) throws IOException{
aoqi@0 411 try{
aoqi@0 412 writeObjectState.writeData(this);
aoqi@0 413
aoqi@0 414 orbStream.write_float(data);
aoqi@0 415 } catch(Error e) {
aoqi@0 416 IOException ioexc = new IOException(e.getMessage());
aoqi@0 417 ioexc.initCause(e) ;
aoqi@0 418 throw ioexc ;
aoqi@0 419 }
aoqi@0 420 }
aoqi@0 421
aoqi@0 422 public final void writeInt(int data) throws IOException{
aoqi@0 423 try{
aoqi@0 424 writeObjectState.writeData(this);
aoqi@0 425
aoqi@0 426 orbStream.write_long(data);
aoqi@0 427 } catch(Error e) {
aoqi@0 428 IOException ioexc = new IOException(e.getMessage());
aoqi@0 429 ioexc.initCause(e) ;
aoqi@0 430 throw ioexc ;
aoqi@0 431 }
aoqi@0 432 }
aoqi@0 433
aoqi@0 434 public final void writeLong(long data) throws IOException{
aoqi@0 435 try{
aoqi@0 436 writeObjectState.writeData(this);
aoqi@0 437
aoqi@0 438 orbStream.write_longlong(data);
aoqi@0 439 } catch(Error e) {
aoqi@0 440 IOException ioexc = new IOException(e.getMessage());
aoqi@0 441 ioexc.initCause(e) ;
aoqi@0 442 throw ioexc ;
aoqi@0 443 }
aoqi@0 444 }
aoqi@0 445
aoqi@0 446 public final void writeShort(int data) throws IOException{
aoqi@0 447 try{
aoqi@0 448 writeObjectState.writeData(this);
aoqi@0 449
aoqi@0 450 orbStream.write_short((short)data);
aoqi@0 451 } catch(Error e) {
aoqi@0 452 IOException ioexc = new IOException(e.getMessage());
aoqi@0 453 ioexc.initCause(e) ;
aoqi@0 454 throw ioexc ;
aoqi@0 455 }
aoqi@0 456 }
aoqi@0 457
aoqi@0 458 protected final void writeStreamHeader() throws IOException{
aoqi@0 459 // no op
aoqi@0 460 }
aoqi@0 461
aoqi@0 462 /**
aoqi@0 463 * Helper method for correcting the Kestrel bug 4367783 (dealing
aoqi@0 464 * with larger than 8-bit chars). The old behavior is preserved
aoqi@0 465 * in orbutil.IIOPInputStream_1_3 in order to interoperate with
aoqi@0 466 * our legacy ORBs.
aoqi@0 467 */
aoqi@0 468 protected void internalWriteUTF(org.omg.CORBA.portable.OutputStream stream,
aoqi@0 469 String data)
aoqi@0 470 {
aoqi@0 471 stream.write_wstring(data);
aoqi@0 472 }
aoqi@0 473
aoqi@0 474 public final void writeUTF(String data) throws IOException{
aoqi@0 475 try{
aoqi@0 476 writeObjectState.writeData(this);
aoqi@0 477
aoqi@0 478 internalWriteUTF(orbStream, data);
aoqi@0 479 } catch(Error e) {
aoqi@0 480 IOException ioexc = new IOException(e.getMessage());
aoqi@0 481 ioexc.initCause(e) ;
aoqi@0 482 throw ioexc ;
aoqi@0 483 }
aoqi@0 484 }
aoqi@0 485
aoqi@0 486 // INTERNAL UTILITY METHODS
aoqi@0 487 /*
aoqi@0 488 * Check for special cases of serializing objects.
aoqi@0 489 * These objects are not subject to replacement.
aoqi@0 490 */
aoqi@0 491 private boolean checkSpecialClasses(Object obj) throws IOException {
aoqi@0 492
aoqi@0 493 /*
aoqi@0 494 * If this is a class, don't allow substitution
aoqi@0 495 */
aoqi@0 496 //if (obj instanceof Class) {
aoqi@0 497 // throw new IOException("Serialization of Class not supported");
aoqi@0 498 //}
aoqi@0 499
aoqi@0 500 if (obj instanceof ObjectStreamClass) {
aoqi@0 501 // XXX I18N, Logging needed.
aoqi@0 502 throw new IOException("Serialization of ObjectStreamClass not supported");
aoqi@0 503 }
aoqi@0 504
aoqi@0 505 return false;
aoqi@0 506 }
aoqi@0 507
aoqi@0 508 /*
aoqi@0 509 * Check for special cases of substitutable serializing objects.
aoqi@0 510 * These classes are replaceable.
aoqi@0 511 */
aoqi@0 512 private boolean checkSubstitutableSpecialClasses(Object obj)
aoqi@0 513 throws IOException
aoqi@0 514 {
aoqi@0 515 if (obj instanceof String) {
aoqi@0 516 orbStream.write_value((java.io.Serializable)obj);
aoqi@0 517 return true;
aoqi@0 518 }
aoqi@0 519
aoqi@0 520 //if (obj.getClass().isArray()) {
aoqi@0 521 // outputArray(obj);
aoqi@0 522 // return true;
aoqi@0 523 //}
aoqi@0 524
aoqi@0 525 return false;
aoqi@0 526 }
aoqi@0 527
aoqi@0 528 /*
aoqi@0 529 * Write out the object
aoqi@0 530 */
aoqi@0 531 private void outputObject(final Object obj) throws IOException{
aoqi@0 532
aoqi@0 533 currentObject = obj;
aoqi@0 534 Class currclass = obj.getClass();
aoqi@0 535
aoqi@0 536 /* Get the Class descriptor for this class,
aoqi@0 537 * Throw a NotSerializableException if there is none.
aoqi@0 538 */
aoqi@0 539 currentClassDesc = ObjectStreamClass.lookup(currclass);
aoqi@0 540 if (currentClassDesc == null) {
aoqi@0 541 // XXX I18N, Logging needed.
aoqi@0 542 throw new NotSerializableException(currclass.getName());
aoqi@0 543 }
aoqi@0 544
aoqi@0 545 /* If the object is externalizable,
aoqi@0 546 * call writeExternal.
aoqi@0 547 * else do Serializable processing.
aoqi@0 548 */
aoqi@0 549 if (currentClassDesc.isExternalizable()) {
aoqi@0 550 // Write format version
aoqi@0 551 orbStream.write_octet(streamFormatVersion);
aoqi@0 552
aoqi@0 553 Externalizable ext = (Externalizable)obj;
aoqi@0 554 ext.writeExternal(this);
aoqi@0 555
aoqi@0 556 } else {
aoqi@0 557
aoqi@0 558 /* The object's classes should be processed from supertype to subtype
aoqi@0 559 * Push all the clases of the current object onto a stack.
aoqi@0 560 * Remember the stack pointer where this set of classes is being pushed.
aoqi@0 561 */
aoqi@0 562 int stackMark = classDescStack.size();
aoqi@0 563 try {
aoqi@0 564 ObjectStreamClass next;
aoqi@0 565 while ((next = currentClassDesc.getSuperclass()) != null) {
aoqi@0 566 classDescStack.push(currentClassDesc);
aoqi@0 567 currentClassDesc = next;
aoqi@0 568 }
aoqi@0 569
aoqi@0 570 /*
aoqi@0 571 * For currentClassDesc and all the pushed class descriptors
aoqi@0 572 * If the class is writing its own data
aoqi@0 573 * set blockData = true; call the class writeObject method
aoqi@0 574 * If not
aoqi@0 575 * invoke either the defaultWriteObject method.
aoqi@0 576 */
aoqi@0 577 do {
aoqi@0 578
aoqi@0 579 WriteObjectState oldState = writeObjectState;
aoqi@0 580
aoqi@0 581 try {
aoqi@0 582
aoqi@0 583 setState(NOT_IN_WRITE_OBJECT);
aoqi@0 584
aoqi@0 585 if (currentClassDesc.hasWriteObject()) {
aoqi@0 586 invokeObjectWriter(currentClassDesc, obj );
aoqi@0 587 } else {
aoqi@0 588 defaultWriteObjectDelegate();
aoqi@0 589 }
aoqi@0 590 } finally {
aoqi@0 591 setState(oldState);
aoqi@0 592 }
aoqi@0 593
aoqi@0 594 } while (classDescStack.size() > stackMark &&
aoqi@0 595 (currentClassDesc = (ObjectStreamClass)classDescStack.pop()) != null);
aoqi@0 596 } finally {
aoqi@0 597 classDescStack.setSize(stackMark);
aoqi@0 598 }
aoqi@0 599 }
aoqi@0 600 }
aoqi@0 601
aoqi@0 602 /*
aoqi@0 603 * Invoke writer.
aoqi@0 604 * _REVISIT_ invokeObjectWriter and invokeObjectReader behave inconsistently with each other since
aoqi@0 605 * the reader returns a boolean...fix later
aoqi@0 606 */
aoqi@0 607 private void invokeObjectWriter(ObjectStreamClass osc, Object obj)
aoqi@0 608 throws IOException
aoqi@0 609 {
aoqi@0 610 Class c = osc.forClass() ;
aoqi@0 611
aoqi@0 612 try {
aoqi@0 613
aoqi@0 614 // Write format version
aoqi@0 615 orbStream.write_octet(streamFormatVersion);
aoqi@0 616
aoqi@0 617 writeObjectState.enterWriteObject(this);
aoqi@0 618
aoqi@0 619 // writeObject(obj, c, this);
aoqi@0 620 osc.writeObjectMethod.invoke( obj, writeObjectArgList ) ;
aoqi@0 621
aoqi@0 622 writeObjectState.exitWriteObject(this);
aoqi@0 623
aoqi@0 624 } catch (InvocationTargetException e) {
aoqi@0 625 Throwable t = e.getTargetException();
aoqi@0 626 if (t instanceof IOException)
aoqi@0 627 throw (IOException)t;
aoqi@0 628 else if (t instanceof RuntimeException)
aoqi@0 629 throw (RuntimeException) t;
aoqi@0 630 else if (t instanceof Error)
aoqi@0 631 throw (Error) t;
aoqi@0 632 else
aoqi@0 633 // XXX I18N, Logging needed.
aoqi@0 634 throw new Error("invokeObjectWriter internal error",e);
aoqi@0 635 } catch (IllegalAccessException e) {
aoqi@0 636 // cannot happen
aoqi@0 637 }
aoqi@0 638 }
aoqi@0 639
aoqi@0 640 void writeField(ObjectStreamField field, Object value) throws IOException {
aoqi@0 641 switch (field.getTypeCode()) {
aoqi@0 642 case 'B':
aoqi@0 643 if (value == null)
aoqi@0 644 orbStream.write_octet((byte)0);
aoqi@0 645 else
aoqi@0 646 orbStream.write_octet(((Byte)value).byteValue());
aoqi@0 647 break;
aoqi@0 648 case 'C':
aoqi@0 649 if (value == null)
aoqi@0 650 orbStream.write_wchar((char)0);
aoqi@0 651 else
aoqi@0 652 orbStream.write_wchar(((Character)value).charValue());
aoqi@0 653 break;
aoqi@0 654 case 'F':
aoqi@0 655 if (value == null)
aoqi@0 656 orbStream.write_float((float)0);
aoqi@0 657 else
aoqi@0 658 orbStream.write_float(((Float)value).floatValue());
aoqi@0 659 break;
aoqi@0 660 case 'D':
aoqi@0 661 if (value == null)
aoqi@0 662 orbStream.write_double((double)0);
aoqi@0 663 else
aoqi@0 664 orbStream.write_double(((Double)value).doubleValue());
aoqi@0 665 break;
aoqi@0 666 case 'I':
aoqi@0 667 if (value == null)
aoqi@0 668 orbStream.write_long((int)0);
aoqi@0 669 else
aoqi@0 670 orbStream.write_long(((Integer)value).intValue());
aoqi@0 671 break;
aoqi@0 672 case 'J':
aoqi@0 673 if (value == null)
aoqi@0 674 orbStream.write_longlong((long)0);
aoqi@0 675 else
aoqi@0 676 orbStream.write_longlong(((Long)value).longValue());
aoqi@0 677 break;
aoqi@0 678 case 'S':
aoqi@0 679 if (value == null)
aoqi@0 680 orbStream.write_short((short)0);
aoqi@0 681 else
aoqi@0 682 orbStream.write_short(((Short)value).shortValue());
aoqi@0 683 break;
aoqi@0 684 case 'Z':
aoqi@0 685 if (value == null)
aoqi@0 686 orbStream.write_boolean(false);
aoqi@0 687 else
aoqi@0 688 orbStream.write_boolean(((Boolean)value).booleanValue());
aoqi@0 689 break;
aoqi@0 690 case '[':
aoqi@0 691 case 'L':
aoqi@0 692 // What to do if it's null?
aoqi@0 693 writeObjectField(field, value);
aoqi@0 694 break;
aoqi@0 695 default:
aoqi@0 696 // XXX I18N, Logging needed.
aoqi@0 697 throw new InvalidClassException(currentClassDesc.getName());
aoqi@0 698 }
aoqi@0 699 }
aoqi@0 700
aoqi@0 701 private void writeObjectField(ObjectStreamField field,
aoqi@0 702 Object objectValue) throws IOException {
aoqi@0 703
aoqi@0 704 if (ObjectStreamClassCorbaExt.isAny(field.getTypeString())) {
aoqi@0 705 javax.rmi.CORBA.Util.writeAny(orbStream, objectValue);
aoqi@0 706 }
aoqi@0 707 else {
aoqi@0 708 Class type = field.getType();
aoqi@0 709 int callType = ValueHandlerImpl.kValueType;
aoqi@0 710
aoqi@0 711 if (type.isInterface()) {
aoqi@0 712 String className = type.getName();
aoqi@0 713
aoqi@0 714 if (java.rmi.Remote.class.isAssignableFrom(type)) {
aoqi@0 715
aoqi@0 716 // RMI Object reference...
aoqi@0 717
aoqi@0 718 callType = ValueHandlerImpl.kRemoteType;
aoqi@0 719
aoqi@0 720
aoqi@0 721 } else if (org.omg.CORBA.Object.class.isAssignableFrom(type)){
aoqi@0 722
aoqi@0 723 // IDL Object reference...
aoqi@0 724 callType = ValueHandlerImpl.kRemoteType;
aoqi@0 725
aoqi@0 726 } else if (RepositoryId.isAbstractBase(type)) {
aoqi@0 727 // IDL Abstract Object reference...
aoqi@0 728 callType = ValueHandlerImpl.kAbstractType;
aoqi@0 729 } else if (ObjectStreamClassCorbaExt.isAbstractInterface(type)) {
aoqi@0 730 callType = ValueHandlerImpl.kAbstractType;
aoqi@0 731 }
aoqi@0 732 }
aoqi@0 733
aoqi@0 734 switch (callType) {
aoqi@0 735 case ValueHandlerImpl.kRemoteType:
aoqi@0 736 Util.writeRemoteObject(orbStream, objectValue);
aoqi@0 737 break;
aoqi@0 738 case ValueHandlerImpl.kAbstractType:
aoqi@0 739 Util.writeAbstractObject(orbStream, objectValue);
aoqi@0 740 break;
aoqi@0 741 case ValueHandlerImpl.kValueType:
aoqi@0 742 try{
aoqi@0 743 orbStream.write_value((java.io.Serializable)objectValue, type);
aoqi@0 744 }
aoqi@0 745 catch(ClassCastException cce){
aoqi@0 746 if (objectValue instanceof java.io.Serializable)
aoqi@0 747 throw cce;
aoqi@0 748 else
aoqi@0 749 Utility.throwNotSerializableForCorba(objectValue.getClass().getName());
aoqi@0 750 }
aoqi@0 751 }
aoqi@0 752 }
aoqi@0 753 }
aoqi@0 754
aoqi@0 755 /* Write the fields of the specified class by invoking the appropriate
aoqi@0 756 * write* method on this class.
aoqi@0 757 */
aoqi@0 758 private void outputClassFields(Object o, Class cl,
aoqi@0 759 ObjectStreamField[] fields)
aoqi@0 760 throws IOException, InvalidClassException {
aoqi@0 761
aoqi@0 762 for (int i = 0; i < fields.length; i++) {
aoqi@0 763 if (fields[i].getField() == null)
aoqi@0 764 // XXX I18N, Logging needed.
aoqi@0 765 throw new InvalidClassException(cl.getName(),
aoqi@0 766 "Nonexistent field " + fields[i].getName());
aoqi@0 767
aoqi@0 768 try {
aoqi@0 769 switch (fields[i].getTypeCode()) {
aoqi@0 770 case 'B':
aoqi@0 771 byte byteValue = fields[i].getField().getByte( o ) ;
aoqi@0 772 orbStream.write_octet(byteValue);
aoqi@0 773 break;
aoqi@0 774 case 'C':
aoqi@0 775 char charValue = fields[i].getField().getChar( o ) ;
aoqi@0 776 orbStream.write_wchar(charValue);
aoqi@0 777 break;
aoqi@0 778 case 'F':
aoqi@0 779 float floatValue = fields[i].getField().getFloat( o ) ;
aoqi@0 780 orbStream.write_float(floatValue);
aoqi@0 781 break;
aoqi@0 782 case 'D' :
aoqi@0 783 double doubleValue = fields[i].getField().getDouble( o ) ;
aoqi@0 784 orbStream.write_double(doubleValue);
aoqi@0 785 break;
aoqi@0 786 case 'I':
aoqi@0 787 int intValue = fields[i].getField().getInt( o ) ;
aoqi@0 788 orbStream.write_long(intValue);
aoqi@0 789 break;
aoqi@0 790 case 'J':
aoqi@0 791 long longValue = fields[i].getField().getLong( o ) ;
aoqi@0 792 orbStream.write_longlong(longValue);
aoqi@0 793 break;
aoqi@0 794 case 'S':
aoqi@0 795 short shortValue = fields[i].getField().getShort( o ) ;
aoqi@0 796 orbStream.write_short(shortValue);
aoqi@0 797 break;
aoqi@0 798 case 'Z':
aoqi@0 799 boolean booleanValue = fields[i].getField().getBoolean( o ) ;
aoqi@0 800 orbStream.write_boolean(booleanValue);
aoqi@0 801 break;
aoqi@0 802 case '[':
aoqi@0 803 case 'L':
aoqi@0 804 Object objectValue = fields[i].getField().get( o ) ;
aoqi@0 805 writeObjectField(fields[i], objectValue);
aoqi@0 806 break;
aoqi@0 807 default:
aoqi@0 808 // XXX I18N, Logging needed.
aoqi@0 809 throw new InvalidClassException(cl.getName());
aoqi@0 810 }
aoqi@0 811 } catch (IllegalAccessException exc) {
aoqi@0 812 throw wrapper.illegalFieldAccess( exc, fields[i].getName() ) ;
aoqi@0 813 }
aoqi@0 814 }
aoqi@0 815 }
aoqi@0 816 }

mercurial