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

Mon, 16 Oct 2017 15:59:03 +0800

author
aoqi
date
Mon, 16 Oct 2017 15:59:03 +0800
changeset 1022
6081f57a0021
parent 993
fd75ec7ff603
parent 748
6845b95cba6b
child 1410
9c913ea7e4a1
permissions
-rw-r--r--

merge

aoqi@0 1 /*
msheppar@940 2 * Copyright (c) 1998, 2015, 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 java.io.InputStream;
aoqi@0 35 import java.io.IOException;
aoqi@0 36 import java.io.StreamCorruptedException;
aoqi@0 37 import java.io.ObjectInputValidation;
aoqi@0 38 import java.io.NotActiveException;
aoqi@0 39 import java.io.InvalidObjectException;
aoqi@0 40 import java.io.InvalidClassException;
aoqi@0 41 import java.io.DataInputStream;
aoqi@0 42 import java.io.OptionalDataException;
aoqi@0 43 import java.io.WriteAbortedException;
aoqi@0 44 import java.io.Externalizable;
aoqi@0 45 import java.io.EOFException;
aoqi@0 46 import java.lang.reflect.*;
aoqi@0 47 import java.util.Vector;
aoqi@0 48 import java.util.Stack;
aoqi@0 49 import java.util.Hashtable;
aoqi@0 50 import java.util.Enumeration;
aoqi@0 51
aoqi@0 52 import sun.corba.Bridge ;
aoqi@0 53
aoqi@0 54 import java.security.AccessController ;
aoqi@0 55 import java.security.PrivilegedAction ;
aoqi@0 56
aoqi@0 57 import com.sun.corba.se.impl.io.ObjectStreamClass;
aoqi@0 58 import com.sun.corba.se.impl.util.Utility;
aoqi@0 59
aoqi@0 60 import org.omg.CORBA.portable.ValueInputStream;
aoqi@0 61
aoqi@0 62 import org.omg.CORBA.ValueMember;
aoqi@0 63 import org.omg.CORBA.SystemException;
aoqi@0 64 import org.omg.CORBA.TCKind;
aoqi@0 65 import org.omg.CORBA.ORB;
aoqi@0 66 import org.omg.CORBA.CompletionStatus;
aoqi@0 67 import org.omg.CORBA.portable.IndirectionException;
aoqi@0 68 import org.omg.CORBA.MARSHAL;
aoqi@0 69 import org.omg.CORBA.TypeCode;
aoqi@0 70
aoqi@0 71 import com.sun.org.omg.CORBA.ValueDefPackage.FullValueDescription;
aoqi@0 72 import com.sun.org.omg.SendingContext.CodeBase;
aoqi@0 73
aoqi@0 74 import javax.rmi.PortableRemoteObject;
aoqi@0 75 import javax.rmi.CORBA.Util;
aoqi@0 76 import javax.rmi.CORBA.ValueHandler;
aoqi@0 77
aoqi@0 78 import java.security.*;
aoqi@0 79 import java.util.*;
aoqi@0 80
aoqi@0 81 import com.sun.corba.se.impl.orbutil.ObjectUtility ;
aoqi@0 82 import com.sun.corba.se.impl.logging.OMGSystemException ;
aoqi@0 83 import com.sun.corba.se.impl.logging.UtilSystemException ;
aoqi@0 84
aoqi@0 85 import com.sun.corba.se.spi.logging.CORBALogDomains ;
aoqi@0 86
aoqi@0 87 /**
aoqi@0 88 * IIOPInputStream is used by the ValueHandlerImpl to handle Java serialization
aoqi@0 89 * input semantics.
aoqi@0 90 *
aoqi@0 91 * @author Stephen Lewallen
aoqi@0 92 * @since JDK1.1.6
aoqi@0 93 */
aoqi@0 94
aoqi@0 95 public class IIOPInputStream
aoqi@0 96 extends com.sun.corba.se.impl.io.InputStreamHook
aoqi@0 97 {
aoqi@0 98 private static Bridge bridge =
aoqi@0 99 (Bridge)AccessController.doPrivileged(
aoqi@0 100 new PrivilegedAction() {
aoqi@0 101 public Object run() {
aoqi@0 102 return Bridge.get() ;
aoqi@0 103 }
aoqi@0 104 }
aoqi@0 105 ) ;
aoqi@0 106
aoqi@0 107 private static OMGSystemException omgWrapper = OMGSystemException.get(
aoqi@0 108 CORBALogDomains.RPC_ENCODING ) ;
aoqi@0 109 private static UtilSystemException utilWrapper = UtilSystemException.get(
aoqi@0 110 CORBALogDomains.RPC_ENCODING ) ;
aoqi@0 111
aoqi@0 112 // Necessary to pass the appropriate fields into the
aoqi@0 113 // defaultReadObjectDelegate method (which takes no
aoqi@0 114 // parameters since it's called from
aoqi@0 115 // java.io.ObjectInpuStream defaultReadObject()
aoqi@0 116 // which we can't change).
aoqi@0 117 //
aoqi@0 118 // This is only used in the case where the fields had
aoqi@0 119 // to be obtained remotely because of a serializable
aoqi@0 120 // version difference. Set in inputObjectUsingFVD.
aoqi@0 121 // Part of serialization evolution fixes for Ladybird,
aoqi@0 122 // bug 4365188.
aoqi@0 123 private ValueMember defaultReadObjectFVDMembers[] = null;
aoqi@0 124
aoqi@0 125 private org.omg.CORBA_2_3.portable.InputStream orbStream;
aoqi@0 126
aoqi@0 127 private CodeBase cbSender;
aoqi@0 128
aoqi@0 129 private ValueHandlerImpl vhandler; //d4365188
aoqi@0 130
aoqi@0 131 private Object currentObject = null;
aoqi@0 132
aoqi@0 133 private ObjectStreamClass currentClassDesc = null;
aoqi@0 134
aoqi@0 135 private Class currentClass = null;
aoqi@0 136
aoqi@0 137 private int recursionDepth = 0;
aoqi@0 138
aoqi@0 139 private int simpleReadDepth = 0;
aoqi@0 140
aoqi@0 141 // The ActiveRecursionManager replaces the old RecursionManager which
aoqi@0 142 // used to record how many recursions were made, and resolve them after
aoqi@0 143 // an object was completely deserialized.
aoqi@0 144 //
aoqi@0 145 // That created problems (as in bug 4414154) because when custom
aoqi@0 146 // unmarshaling in readObject, there can be recursive references
aoqi@0 147 // to one of the objects currently being unmarshaled, and the
aoqi@0 148 // passive recursion system failed.
aoqi@0 149 ActiveRecursionManager activeRecursionMgr = new ActiveRecursionManager();
aoqi@0 150
aoqi@0 151 private IOException abortIOException = null;
aoqi@0 152
aoqi@0 153 /* Remember the first exception that stopped this stream. */
aoqi@0 154 private ClassNotFoundException abortClassNotFoundException = null;
aoqi@0 155
aoqi@0 156 /* Vector of validation callback objects
aoqi@0 157 * The vector is created as needed. The vector is maintained in
aoqi@0 158 * order of highest (first) priority to lowest
aoqi@0 159 */
aoqi@0 160 private Vector callbacks;
aoqi@0 161
aoqi@0 162 // Serialization machinery fields
aoqi@0 163 /* Arrays used to keep track of classes and ObjectStreamClasses
aoqi@0 164 * as they are being merged; used in inputObject.
aoqi@0 165 * spClass is the stack pointer for both. */
aoqi@0 166 ObjectStreamClass[] classdesc;
aoqi@0 167 Class[] classes;
aoqi@0 168 int spClass;
aoqi@0 169
aoqi@0 170 private static final String kEmptyStr = "";
aoqi@0 171
aoqi@0 172 // TCKind TypeCodes used in FVD inputClassFields
aoqi@0 173 //public static final TypeCode kRemoteTypeCode = new TypeCodeImpl(TCKind._tk_objref);
aoqi@0 174 //public static final TypeCode kValueTypeCode = new TypeCodeImpl(TCKind._tk_value);
aoqi@0 175 // removed TypeCodeImpl dependency
aoqi@0 176 public static final TypeCode kRemoteTypeCode = ORB.init().get_primitive_tc(TCKind.tk_objref);
aoqi@0 177 public static final TypeCode kValueTypeCode = ORB.init().get_primitive_tc(TCKind.tk_value);
aoqi@0 178
aoqi@0 179 // TESTING CODE - useFVDOnly should be made final before FCS in order to
aoqi@0 180 // optimize out the check.
aoqi@0 181 private static final boolean useFVDOnly = false;
aoqi@0 182
aoqi@0 183 private byte streamFormatVersion;
aoqi@0 184
aoqi@0 185 // Since java.io.OptionalDataException's constructors are
aoqi@0 186 // package private, but we need to throw it in some special
aoqi@0 187 // cases, we try to do it by reflection.
aoqi@0 188 private static final Constructor OPT_DATA_EXCEPTION_CTOR;
aoqi@0 189
aoqi@0 190 private Object[] readObjectArgList = { this } ;
aoqi@0 191
aoqi@0 192 static {
aoqi@0 193 OPT_DATA_EXCEPTION_CTOR = getOptDataExceptionCtor();
aoqi@0 194 }
aoqi@0 195
aoqi@0 196 // Grab the OptionalDataException boolean ctor and make
aoqi@0 197 // it accessible. Note that any exceptions
aoqi@0 198 // will be wrapped in ExceptionInInitializerErrors.
aoqi@0 199 private static Constructor getOptDataExceptionCtor() {
aoqi@0 200
aoqi@0 201 try {
aoqi@0 202
aoqi@0 203 Constructor result =
aoqi@0 204
aoqi@0 205 (Constructor) AccessController.doPrivileged(
aoqi@0 206 new PrivilegedExceptionAction() {
aoqi@0 207 public java.lang.Object run()
aoqi@0 208 throws NoSuchMethodException,
aoqi@0 209 SecurityException {
aoqi@0 210
aoqi@0 211 Constructor boolCtor
aoqi@0 212 = OptionalDataException.class.getDeclaredConstructor(
aoqi@0 213 new Class[] {
aoqi@0 214 Boolean.TYPE });
aoqi@0 215
aoqi@0 216 boolCtor.setAccessible(true);
aoqi@0 217
aoqi@0 218 return boolCtor;
aoqi@0 219 }});
aoqi@0 220
aoqi@0 221 if (result == null)
aoqi@0 222 // XXX I18N, logging needed.
aoqi@0 223 throw new Error("Unable to find OptionalDataException constructor");
aoqi@0 224
aoqi@0 225 return result;
aoqi@0 226
aoqi@0 227 } catch (Exception ex) {
aoqi@0 228 // XXX I18N, logging needed.
aoqi@0 229 throw new ExceptionInInitializerError(ex);
aoqi@0 230 }
aoqi@0 231 }
aoqi@0 232
aoqi@0 233 // Create a new OptionalDataException with the EOF marker
aoqi@0 234 // set to true. See handleOptionalDataMarshalException.
aoqi@0 235 private OptionalDataException createOptionalDataException() {
aoqi@0 236 try {
aoqi@0 237 OptionalDataException result
aoqi@0 238 = (OptionalDataException)
aoqi@0 239 OPT_DATA_EXCEPTION_CTOR.newInstance(new Object[] {
aoqi@0 240 Boolean.TRUE });
aoqi@0 241
aoqi@0 242 if (result == null)
aoqi@0 243 // XXX I18N, logging needed.
aoqi@0 244 throw new Error("Created null OptionalDataException");
aoqi@0 245
aoqi@0 246 return result;
aoqi@0 247
aoqi@0 248 } catch (Exception ex) {
aoqi@0 249 // XXX I18N, logging needed.
aoqi@0 250 throw new Error("Couldn't create OptionalDataException", ex);
aoqi@0 251 }
aoqi@0 252 }
aoqi@0 253
aoqi@0 254 // Return the stream format version currently being used
aoqi@0 255 // to deserialize an object
aoqi@0 256 protected byte getStreamFormatVersion() {
aoqi@0 257 return streamFormatVersion;
aoqi@0 258 }
aoqi@0 259
aoqi@0 260 // At the beginning of data sent by a writeObject or
aoqi@0 261 // writeExternal method there is a byte telling the
aoqi@0 262 // reader the stream format version.
aoqi@0 263 private void readFormatVersion() throws IOException {
aoqi@0 264
aoqi@0 265 streamFormatVersion = orbStream.read_octet();
aoqi@0 266
aoqi@0 267 if (streamFormatVersion < 1 ||
aoqi@0 268 streamFormatVersion > vhandler.getMaximumStreamFormatVersion()) {
aoqi@0 269 SystemException sysex = omgWrapper.unsupportedFormatVersion(
aoqi@0 270 CompletionStatus.COMPLETED_MAYBE);
aoqi@0 271 // XXX I18N? Logging for IOException?
aoqi@0 272 IOException result = new IOException("Unsupported format version: "
aoqi@0 273 + streamFormatVersion);
aoqi@0 274 result.initCause( sysex ) ;
aoqi@0 275 throw result ;
aoqi@0 276 }
aoqi@0 277
aoqi@0 278 if (streamFormatVersion == 2) {
aoqi@0 279 if (!(orbStream instanceof ValueInputStream)) {
aoqi@0 280 SystemException sysex = omgWrapper.notAValueinputstream(
aoqi@0 281 CompletionStatus.COMPLETED_MAYBE);
aoqi@0 282 // XXX I18N? Logging for IOException?
aoqi@0 283 IOException result = new IOException("Not a ValueInputStream");
aoqi@0 284 result.initCause( sysex ) ;
aoqi@0 285 throw result;
aoqi@0 286 }
aoqi@0 287 }
aoqi@0 288 }
aoqi@0 289
aoqi@0 290 public static void setTestFVDFlag(boolean val){
aoqi@0 291 // useFVDOnly = val;
aoqi@0 292 }
aoqi@0 293
aoqi@0 294 /**
aoqi@0 295 * Dummy constructor; passes upper stream a dummy stream;
aoqi@0 296 **/
aoqi@0 297 public IIOPInputStream()
aoqi@0 298 throws java.io.IOException {
aoqi@0 299 super();
aoqi@0 300 resetStream();
aoqi@0 301 }
aoqi@0 302
aoqi@0 303 final void setOrbStream(org.omg.CORBA_2_3.portable.InputStream os) {
aoqi@0 304 orbStream = os;
aoqi@0 305 }
aoqi@0 306
aoqi@0 307 final org.omg.CORBA_2_3.portable.InputStream getOrbStream() {
aoqi@0 308 return orbStream;
aoqi@0 309 }
aoqi@0 310
aoqi@0 311 //added setSender and getSender
aoqi@0 312 public final void setSender(CodeBase cb) {
aoqi@0 313 cbSender = cb;
aoqi@0 314 }
aoqi@0 315
aoqi@0 316 public final CodeBase getSender() {
aoqi@0 317 return cbSender;
aoqi@0 318 }
aoqi@0 319
aoqi@0 320 // 4365188 this is added to enable backward compatability w/ wrong
aoqi@0 321 // rep-ids
aoqi@0 322 public final void setValueHandler(ValueHandler vh) {
aoqi@0 323 vhandler = (com.sun.corba.se.impl.io.ValueHandlerImpl) vh;
aoqi@0 324 }
aoqi@0 325
aoqi@0 326 public final ValueHandler getValueHandler() {
aoqi@0 327 return (javax.rmi.CORBA.ValueHandler) vhandler;
aoqi@0 328 }
aoqi@0 329
aoqi@0 330 final void increaseRecursionDepth(){
aoqi@0 331 recursionDepth++;
aoqi@0 332 }
aoqi@0 333
aoqi@0 334 final int decreaseRecursionDepth(){
aoqi@0 335 return --recursionDepth;
aoqi@0 336 }
aoqi@0 337
aoqi@0 338 /**
aoqi@0 339 * Override the actions of the final method "readObject()"
aoqi@0 340 * in ObjectInputStream.
aoqi@0 341 * @since JDK1.1.6
aoqi@0 342 *
aoqi@0 343 * Read an object from the ObjectInputStream.
aoqi@0 344 * The class of the object, the signature of the class, and the values
aoqi@0 345 * of the non-transient and non-static fields of the class and all
aoqi@0 346 * of its supertypes are read. Default deserializing for a class can be
aoqi@0 347 * overriden using the writeObject and readObject methods.
aoqi@0 348 * Objects referenced by this object are read transitively so
aoqi@0 349 * that a complete equivalent graph of objects is reconstructed by readObject. <p>
aoqi@0 350 *
aoqi@0 351 * The root object is completly restored when all of its fields
aoqi@0 352 * and the objects it references are completely restored. At this
aoqi@0 353 * point the object validation callbacks are executed in order
aoqi@0 354 * based on their registered priorities. The callbacks are
aoqi@0 355 * registered by objects (in the readObject special methods)
aoqi@0 356 * as they are individually restored.
aoqi@0 357 *
aoqi@0 358 * Exceptions are thrown for problems with the InputStream and for classes
aoqi@0 359 * that should not be deserialized. All exceptions are fatal to the
aoqi@0 360 * InputStream and leave it in an indeterminate state; it is up to the caller
aoqi@0 361 * to ignore or recover the stream state.
aoqi@0 362 * @exception java.lang.ClassNotFoundException Class of a serialized object
aoqi@0 363 * cannot be found.
aoqi@0 364 * @exception InvalidClassException Something is wrong with a class used by
aoqi@0 365 * serialization.
aoqi@0 366 * @exception StreamCorruptedException Control information in the
aoqi@0 367 * stream is inconsistent.
aoqi@0 368 * @exception OptionalDataException Primitive data was found in the
aoqi@0 369 * stream instead of objects.
aoqi@0 370 * @exception IOException Any of the usual Input/Output related exceptions.
aoqi@0 371 * @since JDK1.1
aoqi@0 372 */
aoqi@0 373 public final synchronized Object readObjectDelegate() throws IOException
aoqi@0 374 {
aoqi@0 375 try {
aoqi@0 376
aoqi@0 377 readObjectState.readData(this);
aoqi@0 378
aoqi@0 379 return orbStream.read_abstract_interface();
aoqi@0 380 } catch (MARSHAL marshalException) {
aoqi@0 381 handleOptionalDataMarshalException(marshalException, true);
aoqi@0 382 throw marshalException;
aoqi@0 383 } catch(IndirectionException cdrie)
aoqi@0 384 {
aoqi@0 385 // The CDR stream had never seen the given offset before,
aoqi@0 386 // so check the recursion manager (it will throw an
aoqi@0 387 // IOException if it doesn't have a reference, either).
aoqi@0 388 return activeRecursionMgr.getObject(cdrie.offset);
aoqi@0 389 }
aoqi@0 390 }
aoqi@0 391
aoqi@0 392 final synchronized Object simpleReadObject(Class clz,
aoqi@0 393 String repositoryID,
aoqi@0 394 com.sun.org.omg.SendingContext.CodeBase sender,
aoqi@0 395 int offset)
aoqi@0 396 /* throws OptionalDataException, ClassNotFoundException, IOException */
aoqi@0 397 {
aoqi@0 398
aoqi@0 399 /* Save the current state and get ready to read an object. */
aoqi@0 400 Object prevObject = currentObject;
aoqi@0 401 ObjectStreamClass prevClassDesc = currentClassDesc;
aoqi@0 402 Class prevClass = currentClass;
aoqi@0 403 byte oldStreamFormatVersion = streamFormatVersion;
aoqi@0 404
aoqi@0 405 simpleReadDepth++; // Entering
aoqi@0 406 Object obj = null;
aoqi@0 407
aoqi@0 408 /*
aoqi@0 409 * Check for reset, handle it before reading an object.
aoqi@0 410 */
aoqi@0 411 try {
aoqi@0 412 // d4365188: backward compatability
aoqi@0 413 if (vhandler.useFullValueDescription(clz, repositoryID)) {
aoqi@0 414 obj = inputObjectUsingFVD(clz, repositoryID, sender, offset);
aoqi@0 415 } else {
aoqi@0 416 obj = inputObject(clz, repositoryID, sender, offset);
aoqi@0 417 }
aoqi@0 418
aoqi@0 419 obj = currentClassDesc.readResolve(obj);
aoqi@0 420 }
aoqi@0 421 catch(ClassNotFoundException cnfe)
aoqi@0 422 {
aoqi@0 423 bridge.throwException( cnfe ) ;
aoqi@0 424 return null;
aoqi@0 425 }
aoqi@0 426 catch(IOException ioe)
aoqi@0 427 {
aoqi@0 428 // System.out.println("CLZ = " + clz + "; " + ioe.toString());
aoqi@0 429 bridge.throwException(ioe) ;
aoqi@0 430 return null;
aoqi@0 431 }
aoqi@0 432 finally {
aoqi@0 433 simpleReadDepth --;
aoqi@0 434 currentObject = prevObject;
aoqi@0 435 currentClassDesc = prevClassDesc;
aoqi@0 436 currentClass = prevClass;
aoqi@0 437 streamFormatVersion = oldStreamFormatVersion;
aoqi@0 438 }
aoqi@0 439
aoqi@0 440
aoqi@0 441 /* Check for thrown exceptions and re-throw them, clearing them if
aoqi@0 442 * this is the last recursive call .
aoqi@0 443 */
aoqi@0 444 IOException exIOE = abortIOException;
aoqi@0 445 if (simpleReadDepth == 0)
aoqi@0 446 abortIOException = null;
aoqi@0 447 if (exIOE != null){
aoqi@0 448 bridge.throwException( exIOE ) ;
aoqi@0 449 return null;
aoqi@0 450 }
aoqi@0 451
aoqi@0 452
aoqi@0 453 ClassNotFoundException exCNF = abortClassNotFoundException;
aoqi@0 454 if (simpleReadDepth == 0)
aoqi@0 455 abortClassNotFoundException = null;
aoqi@0 456 if (exCNF != null) {
aoqi@0 457 bridge.throwException( exCNF ) ;
aoqi@0 458 return null;
aoqi@0 459 }
aoqi@0 460
aoqi@0 461 return obj;
aoqi@0 462 }
aoqi@0 463
aoqi@0 464 public final synchronized void simpleSkipObject(String repositoryID,
aoqi@0 465 com.sun.org.omg.SendingContext.CodeBase sender)
aoqi@0 466 /* throws OptionalDataException, ClassNotFoundException, IOException */
aoqi@0 467 {
aoqi@0 468
aoqi@0 469 /* Save the current state and get ready to read an object. */
aoqi@0 470 Object prevObject = currentObject;
aoqi@0 471 ObjectStreamClass prevClassDesc = currentClassDesc;
aoqi@0 472 Class prevClass = currentClass;
aoqi@0 473 byte oldStreamFormatVersion = streamFormatVersion;
aoqi@0 474
aoqi@0 475 simpleReadDepth++; // Entering
aoqi@0 476 Object obj = null;
aoqi@0 477
aoqi@0 478 /*
aoqi@0 479 * Check for reset, handle it before reading an object.
aoqi@0 480 */
aoqi@0 481 try {
aoqi@0 482 skipObjectUsingFVD(repositoryID, sender);
aoqi@0 483 }
aoqi@0 484 catch(ClassNotFoundException cnfe)
aoqi@0 485 {
aoqi@0 486 bridge.throwException( cnfe ) ;
aoqi@0 487 return;
aoqi@0 488 }
aoqi@0 489 catch(IOException ioe)
aoqi@0 490 {
aoqi@0 491 bridge.throwException( ioe ) ;
aoqi@0 492 return;
aoqi@0 493 }
aoqi@0 494 finally {
aoqi@0 495 simpleReadDepth --;
aoqi@0 496 streamFormatVersion = oldStreamFormatVersion;
aoqi@0 497 currentObject = prevObject;
aoqi@0 498 currentClassDesc = prevClassDesc;
aoqi@0 499 currentClass = prevClass;
aoqi@0 500 }
aoqi@0 501
aoqi@0 502
aoqi@0 503 /* Check for thrown exceptions and re-throw them, clearing them if
aoqi@0 504 * this is the last recursive call .
aoqi@0 505 */
aoqi@0 506 IOException exIOE = abortIOException;
aoqi@0 507 if (simpleReadDepth == 0)
aoqi@0 508 abortIOException = null;
aoqi@0 509 if (exIOE != null){
aoqi@0 510 bridge.throwException( exIOE ) ;
aoqi@0 511 return;
aoqi@0 512 }
aoqi@0 513
aoqi@0 514
aoqi@0 515 ClassNotFoundException exCNF = abortClassNotFoundException;
aoqi@0 516 if (simpleReadDepth == 0)
aoqi@0 517 abortClassNotFoundException = null;
aoqi@0 518 if (exCNF != null) {
aoqi@0 519 bridge.throwException( exCNF ) ;
aoqi@0 520 return;
aoqi@0 521 }
aoqi@0 522
aoqi@0 523 return;
aoqi@0 524 }
aoqi@0 525 /////////////////
aoqi@0 526
aoqi@0 527 /**
aoqi@0 528 * This method is called by trusted subclasses of ObjectOutputStream
aoqi@0 529 * that constructed ObjectOutputStream using the
aoqi@0 530 * protected no-arg constructor. The subclass is expected to provide
aoqi@0 531 * an override method with the modifier "final".
aoqi@0 532 *
aoqi@0 533 * @return the Object read from the stream.
aoqi@0 534 *
aoqi@0 535 * @see #ObjectInputStream()
aoqi@0 536 * @see #readObject
aoqi@0 537 * @since JDK 1.2
aoqi@0 538 */
aoqi@0 539 protected final Object readObjectOverride()
aoqi@0 540 throws OptionalDataException, ClassNotFoundException, IOException
aoqi@0 541 {
aoqi@0 542 return readObjectDelegate();
aoqi@0 543 }
aoqi@0 544
aoqi@0 545 /**
aoqi@0 546 * Override the actions of the final method "defaultReadObject()"
aoqi@0 547 * in ObjectInputStream.
aoqi@0 548 * @since JDK1.1.6
aoqi@0 549 *
aoqi@0 550 * Read the non-static and non-transient fields of the current class
aoqi@0 551 * from this stream. This may only be called from the readObject method
aoqi@0 552 * of the class being deserialized. It will throw the NotActiveException
aoqi@0 553 * if it is called otherwise.
aoqi@0 554 *
aoqi@0 555 * @exception java.lang.ClassNotFoundException if the class of a serialized
aoqi@0 556 * object could not be found.
aoqi@0 557 * @exception IOException if an I/O error occurs.
aoqi@0 558 * @exception NotActiveException if the stream is not currently reading
aoqi@0 559 * objects.
aoqi@0 560 * @since JDK1.1
aoqi@0 561 */
aoqi@0 562 final synchronized void defaultReadObjectDelegate()
aoqi@0 563 /* throws IOException, ClassNotFoundException, NotActiveException */
aoqi@0 564 {
aoqi@0 565 try {
aoqi@0 566 if (currentObject == null || currentClassDesc == null)
aoqi@0 567 // XXX I18N, logging needed.
aoqi@0 568 throw new NotActiveException("defaultReadObjectDelegate");
aoqi@0 569
aoqi@0 570 // The array will be null unless fields were retrieved
aoqi@0 571 // remotely because of a serializable version difference.
aoqi@0 572 // Bug fix for 4365188. See the definition of
aoqi@0 573 // defaultReadObjectFVDMembers for more information.
aoqi@0 574 if (defaultReadObjectFVDMembers != null &&
aoqi@0 575 defaultReadObjectFVDMembers.length > 0) {
aoqi@0 576
aoqi@0 577 // WARNING: Be very careful! What if some of
aoqi@0 578 // these fields actually have to do this, too?
aoqi@0 579 // This works because the defaultReadObjectFVDMembers
aoqi@0 580 // reference is passed to inputClassFields, but
aoqi@0 581 // there is no guarantee that
aoqi@0 582 // defaultReadObjectFVDMembers will point to the
aoqi@0 583 // same array after calling inputClassFields.
aoqi@0 584
aoqi@0 585 // Use the remote fields to unmarshal.
aoqi@0 586 inputClassFields(currentObject,
aoqi@0 587 currentClass,
aoqi@0 588 currentClassDesc,
aoqi@0 589 defaultReadObjectFVDMembers,
aoqi@0 590 cbSender);
aoqi@0 591
aoqi@0 592 } else {
aoqi@0 593
aoqi@0 594 // Use the local fields to unmarshal.
aoqi@0 595 ObjectStreamField[] fields =
aoqi@0 596 currentClassDesc.getFieldsNoCopy();
aoqi@0 597 if (fields.length > 0) {
aoqi@0 598 inputClassFields(currentObject, currentClass, fields, cbSender);
aoqi@0 599 }
aoqi@0 600 }
aoqi@0 601 }
aoqi@0 602 catch(NotActiveException nae)
aoqi@0 603 {
aoqi@0 604 bridge.throwException( nae ) ;
aoqi@0 605 }
aoqi@0 606 catch(IOException ioe)
aoqi@0 607 {
aoqi@0 608 bridge.throwException( ioe ) ;
aoqi@0 609 }
aoqi@0 610 catch(ClassNotFoundException cnfe)
aoqi@0 611 {
aoqi@0 612 bridge.throwException( cnfe ) ;
aoqi@0 613 }
aoqi@0 614
aoqi@0 615 }
aoqi@0 616
aoqi@0 617 /**
aoqi@0 618 * Override the actions of the final method "enableResolveObject()"
aoqi@0 619 * in ObjectInputStream.
aoqi@0 620 * @since JDK1.1.6
aoqi@0 621 *
aoqi@0 622 * Enable the stream to allow objects read from the stream to be replaced.
aoqi@0 623 * If the stream is a trusted class it is allowed to enable replacment.
aoqi@0 624 * Trusted classes are those classes with a classLoader equals null. <p>
aoqi@0 625 *
aoqi@0 626 * When enabled the resolveObject method is called for every object
aoqi@0 627 * being deserialized.
aoqi@0 628 *
aoqi@0 629 * @exception SecurityException The classloader of this stream object is non-null.
aoqi@0 630 * @since JDK1.1
aoqi@0 631 */
aoqi@0 632 public final boolean enableResolveObjectDelegate(boolean enable)
aoqi@0 633 /* throws SecurityException */
aoqi@0 634 {
aoqi@0 635 return false;
aoqi@0 636 }
aoqi@0 637
aoqi@0 638 // The following three methods allow the implementing orbStream
aoqi@0 639 // to provide mark/reset behavior as defined in java.io.InputStream.
aoqi@0 640
aoqi@0 641 public final void mark(int readAheadLimit) {
aoqi@0 642 orbStream.mark(readAheadLimit);
aoqi@0 643 }
aoqi@0 644
aoqi@0 645 public final boolean markSupported() {
aoqi@0 646 return orbStream.markSupported();
aoqi@0 647 }
aoqi@0 648
aoqi@0 649 public final void reset() throws IOException {
aoqi@0 650 try {
aoqi@0 651 orbStream.reset();
aoqi@0 652 } catch (Error e) {
aoqi@0 653 IOException err = new IOException(e.getMessage());
aoqi@0 654 err.initCause(e) ;
aoqi@0 655 throw err ;
aoqi@0 656 }
aoqi@0 657 }
aoqi@0 658
aoqi@0 659 public final int available() throws IOException{
aoqi@0 660 return 0; // unreliable
aoqi@0 661 }
aoqi@0 662
aoqi@0 663 public final void close() throws IOException{
aoqi@0 664 // no op
aoqi@0 665 }
aoqi@0 666
aoqi@0 667 public final int read() throws IOException{
aoqi@0 668 try{
aoqi@0 669 readObjectState.readData(this);
aoqi@0 670
aoqi@0 671 return (orbStream.read_octet() << 0) & 0x000000FF;
aoqi@0 672 } catch (MARSHAL marshalException) {
aoqi@0 673 if (marshalException.minor
aoqi@0 674 == OMGSystemException.RMIIIOP_OPTIONAL_DATA_INCOMPATIBLE1) {
aoqi@0 675 setState(IN_READ_OBJECT_NO_MORE_OPT_DATA);
aoqi@0 676 return -1;
aoqi@0 677 }
aoqi@0 678
aoqi@0 679 throw marshalException;
aoqi@0 680 } catch(Error e) {
aoqi@0 681 IOException exc = new IOException(e.getMessage());
aoqi@0 682 exc.initCause(e) ;
aoqi@0 683 throw exc ;
aoqi@0 684 }
aoqi@0 685 }
aoqi@0 686
aoqi@0 687 public final int read(byte data[], int offset, int length) throws IOException{
aoqi@0 688 try{
aoqi@0 689 readObjectState.readData(this);
aoqi@0 690
aoqi@0 691 orbStream.read_octet_array(data, offset, length);
aoqi@0 692 return length;
aoqi@0 693 } catch (MARSHAL marshalException) {
aoqi@0 694 if (marshalException.minor
aoqi@0 695 == OMGSystemException.RMIIIOP_OPTIONAL_DATA_INCOMPATIBLE1) {
aoqi@0 696 setState(IN_READ_OBJECT_NO_MORE_OPT_DATA);
aoqi@0 697 return -1;
aoqi@0 698 }
aoqi@0 699
aoqi@0 700 throw marshalException;
aoqi@0 701 } catch(Error e) {
aoqi@0 702 IOException exc = new IOException(e.getMessage());
aoqi@0 703 exc.initCause(e) ;
aoqi@0 704 throw exc ;
aoqi@0 705 }
aoqi@0 706
aoqi@0 707 }
aoqi@0 708
aoqi@0 709 public final boolean readBoolean() throws IOException{
aoqi@0 710 try{
aoqi@0 711 readObjectState.readData(this);
aoqi@0 712
aoqi@0 713 return orbStream.read_boolean();
aoqi@0 714 } catch (MARSHAL marshalException) {
aoqi@0 715 handleOptionalDataMarshalException(marshalException, false);
aoqi@0 716 throw marshalException;
aoqi@0 717
aoqi@0 718 } catch(Error e) {
aoqi@0 719 IOException exc = new IOException(e.getMessage());
aoqi@0 720 exc.initCause(e);
aoqi@0 721 throw exc ;
aoqi@0 722 }
aoqi@0 723 }
aoqi@0 724
aoqi@0 725 public final byte readByte() throws IOException{
aoqi@0 726 try{
aoqi@0 727 readObjectState.readData(this);
aoqi@0 728
aoqi@0 729 return orbStream.read_octet();
aoqi@0 730 } catch (MARSHAL marshalException) {
aoqi@0 731 handleOptionalDataMarshalException(marshalException, false);
aoqi@0 732 throw marshalException;
aoqi@0 733
aoqi@0 734 } catch(Error e) {
aoqi@0 735 IOException exc = new IOException(e.getMessage());
aoqi@0 736 exc.initCause(e);
aoqi@0 737 throw exc ;
aoqi@0 738 }
aoqi@0 739 }
aoqi@0 740
aoqi@0 741 public final char readChar() throws IOException{
aoqi@0 742 try{
aoqi@0 743 readObjectState.readData(this);
aoqi@0 744
aoqi@0 745 return orbStream.read_wchar();
aoqi@0 746 } catch (MARSHAL marshalException) {
aoqi@0 747 handleOptionalDataMarshalException(marshalException, false);
aoqi@0 748 throw marshalException;
aoqi@0 749
aoqi@0 750 } catch(Error e) {
aoqi@0 751 IOException exc = new IOException(e.getMessage());
aoqi@0 752 exc.initCause(e);
aoqi@0 753 throw exc ;
aoqi@0 754 }
aoqi@0 755 }
aoqi@0 756
aoqi@0 757 public final double readDouble() throws IOException{
aoqi@0 758 try{
aoqi@0 759 readObjectState.readData(this);
aoqi@0 760
aoqi@0 761 return orbStream.read_double();
aoqi@0 762 } catch (MARSHAL marshalException) {
aoqi@0 763 handleOptionalDataMarshalException(marshalException, false);
aoqi@0 764 throw marshalException;
aoqi@0 765 } catch(Error e) {
aoqi@0 766 IOException exc = new IOException(e.getMessage());
aoqi@0 767 exc.initCause(e);
aoqi@0 768 throw exc ;
aoqi@0 769 }
aoqi@0 770 }
aoqi@0 771
aoqi@0 772 public final float readFloat() throws IOException{
aoqi@0 773 try{
aoqi@0 774 readObjectState.readData(this);
aoqi@0 775
aoqi@0 776 return orbStream.read_float();
aoqi@0 777 } catch (MARSHAL marshalException) {
aoqi@0 778 handleOptionalDataMarshalException(marshalException, false);
aoqi@0 779 throw marshalException;
aoqi@0 780 } catch(Error e) {
aoqi@0 781 IOException exc = new IOException(e.getMessage());
aoqi@0 782 exc.initCause(e);
aoqi@0 783 throw exc ;
aoqi@0 784 }
aoqi@0 785 }
aoqi@0 786
aoqi@0 787 public final void readFully(byte data[]) throws IOException{
aoqi@0 788 // d11623 : implement readFully, required for serializing some core classes
aoqi@0 789
aoqi@0 790 readFully(data, 0, data.length);
aoqi@0 791 }
aoqi@0 792
aoqi@0 793 public final void readFully(byte data[], int offset, int size) throws IOException{
aoqi@0 794 // d11623 : implement readFully, required for serializing some core classes
aoqi@0 795 try{
aoqi@0 796 readObjectState.readData(this);
aoqi@0 797
aoqi@0 798 orbStream.read_octet_array(data, offset, size);
aoqi@0 799 } catch (MARSHAL marshalException) {
aoqi@0 800 handleOptionalDataMarshalException(marshalException, false);
aoqi@0 801
aoqi@0 802 throw marshalException;
aoqi@0 803 } catch(Error e) {
aoqi@0 804 IOException exc = new IOException(e.getMessage());
aoqi@0 805 exc.initCause(e);
aoqi@0 806 throw exc ;
aoqi@0 807 }
aoqi@0 808 }
aoqi@0 809
aoqi@0 810 public final int readInt() throws IOException{
aoqi@0 811 try{
aoqi@0 812 readObjectState.readData(this);
aoqi@0 813
aoqi@0 814 return orbStream.read_long();
aoqi@0 815 } catch (MARSHAL marshalException) {
aoqi@0 816 handleOptionalDataMarshalException(marshalException, false);
aoqi@0 817 throw marshalException;
aoqi@0 818 } catch(Error e) {
aoqi@0 819 IOException exc = new IOException(e.getMessage());
aoqi@0 820 exc.initCause(e);
aoqi@0 821 throw exc ;
aoqi@0 822 }
aoqi@0 823 }
aoqi@0 824
aoqi@0 825 public final String readLine() throws IOException{
aoqi@0 826 // XXX I18N, logging needed.
aoqi@0 827 throw new IOException("Method readLine not supported");
aoqi@0 828 }
aoqi@0 829
aoqi@0 830 public final long readLong() throws IOException{
aoqi@0 831 try{
aoqi@0 832 readObjectState.readData(this);
aoqi@0 833
aoqi@0 834 return orbStream.read_longlong();
aoqi@0 835 } catch (MARSHAL marshalException) {
aoqi@0 836 handleOptionalDataMarshalException(marshalException, false);
aoqi@0 837 throw marshalException;
aoqi@0 838 } catch(Error e) {
aoqi@0 839 IOException exc = new IOException(e.getMessage());
aoqi@0 840 exc.initCause(e);
aoqi@0 841 throw exc ;
aoqi@0 842 }
aoqi@0 843 }
aoqi@0 844
aoqi@0 845 public final short readShort() throws IOException{
aoqi@0 846 try{
aoqi@0 847 readObjectState.readData(this);
aoqi@0 848
aoqi@0 849 return orbStream.read_short();
aoqi@0 850 } catch (MARSHAL marshalException) {
aoqi@0 851 handleOptionalDataMarshalException(marshalException, false);
aoqi@0 852 throw marshalException;
aoqi@0 853 } catch(Error e) {
aoqi@0 854 IOException exc = new IOException(e.getMessage());
aoqi@0 855 exc.initCause(e);
aoqi@0 856 throw exc ;
aoqi@0 857 }
aoqi@0 858 }
aoqi@0 859
aoqi@0 860 protected final void readStreamHeader() throws IOException, StreamCorruptedException{
aoqi@0 861 // no op
aoqi@0 862 }
aoqi@0 863
aoqi@0 864 public final int readUnsignedByte() throws IOException{
aoqi@0 865 try{
aoqi@0 866 readObjectState.readData(this);
aoqi@0 867
aoqi@0 868 return (orbStream.read_octet() << 0) & 0x000000FF;
aoqi@0 869 } catch (MARSHAL marshalException) {
aoqi@0 870 handleOptionalDataMarshalException(marshalException, false);
aoqi@0 871 throw marshalException;
aoqi@0 872 } catch(Error e) {
aoqi@0 873 IOException exc = new IOException(e.getMessage());
aoqi@0 874 exc.initCause(e);
aoqi@0 875 throw exc ;
aoqi@0 876 }
aoqi@0 877 }
aoqi@0 878
aoqi@0 879 public final int readUnsignedShort() throws IOException{
aoqi@0 880 try{
aoqi@0 881 readObjectState.readData(this);
aoqi@0 882
aoqi@0 883 return (orbStream.read_ushort() << 0) & 0x0000FFFF;
aoqi@0 884 } catch (MARSHAL marshalException) {
aoqi@0 885 handleOptionalDataMarshalException(marshalException, false);
aoqi@0 886 throw marshalException;
aoqi@0 887 } catch(Error e) {
aoqi@0 888 IOException exc = new IOException(e.getMessage());
aoqi@0 889 exc.initCause(e);
aoqi@0 890 throw exc ;
aoqi@0 891 }
aoqi@0 892 }
aoqi@0 893
aoqi@0 894 /**
aoqi@0 895 * Helper method for correcting the Kestrel bug 4367783 (dealing
aoqi@0 896 * with larger than 8-bit chars). The old behavior is preserved
aoqi@0 897 * in orbutil.IIOPInputStream_1_3 in order to interoperate with
aoqi@0 898 * our legacy ORBs.
aoqi@0 899 */
aoqi@0 900 protected String internalReadUTF(org.omg.CORBA.portable.InputStream stream)
aoqi@0 901 {
aoqi@0 902 return stream.read_wstring();
aoqi@0 903 }
aoqi@0 904
aoqi@0 905 public final String readUTF() throws IOException{
aoqi@0 906 try{
aoqi@0 907 readObjectState.readData(this);
aoqi@0 908
aoqi@0 909 return internalReadUTF(orbStream);
aoqi@0 910 } catch (MARSHAL marshalException) {
aoqi@0 911 handleOptionalDataMarshalException(marshalException, false);
aoqi@0 912 throw marshalException;
aoqi@0 913 } catch(Error e) {
aoqi@0 914 IOException exc = new IOException(e.getMessage());
aoqi@0 915 exc.initCause(e);
aoqi@0 916 throw exc ;
aoqi@0 917 }
aoqi@0 918 }
aoqi@0 919
aoqi@0 920 // If the ORB stream detects an incompatibility between what's
aoqi@0 921 // on the wire and what our Serializable's readObject wants,
aoqi@0 922 // it throws a MARSHAL exception with a specific minor code.
aoqi@0 923 // This is rethrown to the readObject as an OptionalDataException.
aoqi@0 924 // So far in RMI-IIOP, this process isn't specific enough to
aoqi@0 925 // tell the readObject how much data is available, so we always
aoqi@0 926 // set the OptionalDataException's EOF marker to true.
aoqi@0 927 private void handleOptionalDataMarshalException(MARSHAL marshalException,
aoqi@0 928 boolean objectRead)
aoqi@0 929 throws IOException {
aoqi@0 930
aoqi@0 931 // Java Object Serialization spec 3.4: "If the readObject method
aoqi@0 932 // of the class attempts to read more data than is present in the
aoqi@0 933 // optional part of the stream for this class, the stream will
aoqi@0 934 // return -1 for bytewise reads, throw an EOFException for
aoqi@0 935 // primitive data reads, or throw an OptionalDataException
aoqi@0 936 // with the eof field set to true for object reads."
aoqi@0 937 if (marshalException.minor
aoqi@0 938 == OMGSystemException.RMIIIOP_OPTIONAL_DATA_INCOMPATIBLE1) {
aoqi@0 939
aoqi@0 940 IOException result;
aoqi@0 941
aoqi@0 942 if (!objectRead)
aoqi@0 943 result = new EOFException("No more optional data");
aoqi@0 944 else
aoqi@0 945 result = createOptionalDataException();
aoqi@0 946
aoqi@0 947 result.initCause(marshalException);
aoqi@0 948
aoqi@0 949 setState(IN_READ_OBJECT_NO_MORE_OPT_DATA);
aoqi@0 950
aoqi@0 951 throw result;
aoqi@0 952 }
aoqi@0 953 }
aoqi@0 954
aoqi@0 955 public final synchronized void registerValidation(ObjectInputValidation obj,
aoqi@0 956 int prio)
aoqi@0 957 throws NotActiveException, InvalidObjectException{
aoqi@0 958 // XXX I18N, logging needed.
aoqi@0 959 throw new Error("Method registerValidation not supported");
aoqi@0 960 }
aoqi@0 961
aoqi@0 962 protected final Class resolveClass(ObjectStreamClass v)
aoqi@0 963 throws IOException, ClassNotFoundException{
aoqi@0 964 // XXX I18N, logging needed.
aoqi@0 965 throw new IOException("Method resolveClass not supported");
aoqi@0 966 }
aoqi@0 967
aoqi@0 968 protected final Object resolveObject(Object obj) throws IOException{
aoqi@0 969 // XXX I18N, logging needed.
aoqi@0 970 throw new IOException("Method resolveObject not supported");
aoqi@0 971 }
aoqi@0 972
aoqi@0 973 public final int skipBytes(int len) throws IOException{
aoqi@0 974 try{
aoqi@0 975 readObjectState.readData(this);
aoqi@0 976
aoqi@0 977 byte buf[] = new byte[len];
aoqi@0 978 orbStream.read_octet_array(buf, 0, len);
aoqi@0 979 return len;
aoqi@0 980 } catch (MARSHAL marshalException) {
aoqi@0 981 handleOptionalDataMarshalException(marshalException, false);
aoqi@0 982
aoqi@0 983 throw marshalException;
aoqi@0 984 } catch(Error e) {
aoqi@0 985 IOException exc = new IOException(e.getMessage());
aoqi@0 986 exc.initCause(e) ;
aoqi@0 987 throw exc ;
aoqi@0 988 }
aoqi@0 989 }
aoqi@0 990
aoqi@0 991 private synchronized Object inputObject(Class clz,
aoqi@0 992 String repositoryID,
aoqi@0 993 com.sun.org.omg.SendingContext.CodeBase sender,
aoqi@0 994 int offset)
aoqi@0 995 throws IOException, ClassNotFoundException
aoqi@0 996 {
aoqi@0 997
aoqi@0 998 /*
aoqi@0 999 * Get the descriptor and then class of the incoming object.
aoqi@0 1000 */
aoqi@0 1001
aoqi@0 1002 currentClassDesc = ObjectStreamClass.lookup(clz);
aoqi@0 1003 currentClass = currentClassDesc.forClass();
aoqi@0 1004 //currentClassDesc.setClass(currentClass);
aoqi@0 1005 if (currentClass == null)
aoqi@0 1006 // XXX I18N, logging needed.
aoqi@0 1007 throw new ClassNotFoundException(currentClassDesc.getName());
aoqi@0 1008
aoqi@0 1009 try {
aoqi@0 1010 /* If Externalizable,
aoqi@0 1011 * Create an instance and tell it to read its data.
aoqi@0 1012 * else,
aoqi@0 1013 * Handle it as a serializable class.
aoqi@0 1014 */
aoqi@0 1015 if (Enum.class.isAssignableFrom( clz )) {
aoqi@0 1016 int ordinal = orbStream.read_long() ;
aoqi@0 1017 String value = (String)orbStream.read_value( String.class ) ;
aoqi@0 1018 return Enum.valueOf( clz, value ) ;
aoqi@0 1019 } else if (currentClassDesc.isExternalizable()) {
aoqi@0 1020 try {
aoqi@0 1021 currentObject = (currentClass == null) ?
aoqi@0 1022 null : currentClassDesc.newInstance();
aoqi@0 1023 if (currentObject != null) {
aoqi@0 1024
aoqi@0 1025 // Store this object and its beginning position
aoqi@0 1026 // since there might be indirections to it while
aoqi@0 1027 // it's been unmarshalled.
aoqi@0 1028 activeRecursionMgr.addObject(offset, currentObject);
aoqi@0 1029
aoqi@0 1030 // Read format version
aoqi@0 1031 readFormatVersion();
aoqi@0 1032
aoqi@0 1033 Externalizable ext = (Externalizable)currentObject;
aoqi@0 1034 ext.readExternal(this);
aoqi@0 1035 }
aoqi@0 1036 } catch (InvocationTargetException e) {
aoqi@0 1037 InvalidClassException exc = new InvalidClassException(
aoqi@0 1038 currentClass.getName(),
aoqi@0 1039 "InvocationTargetException accessing no-arg constructor");
aoqi@0 1040 exc.initCause( e ) ;
aoqi@0 1041 throw exc ;
aoqi@0 1042 } catch (UnsupportedOperationException e) {
aoqi@0 1043 InvalidClassException exc = new InvalidClassException(
aoqi@0 1044 currentClass.getName(),
aoqi@0 1045 "UnsupportedOperationException accessing no-arg constructor");
aoqi@0 1046 exc.initCause( e ) ;
aoqi@0 1047 throw exc ;
aoqi@0 1048 } catch (InstantiationException e) {
aoqi@0 1049 InvalidClassException exc = new InvalidClassException(
aoqi@0 1050 currentClass.getName(),
aoqi@0 1051 "InstantiationException accessing no-arg constructor");
aoqi@0 1052 exc.initCause( e ) ;
aoqi@0 1053 throw exc ;
aoqi@0 1054 }
aoqi@0 1055 } // end : if (currentClassDesc.isExternalizable())
aoqi@0 1056 else {
aoqi@0 1057 /* Count number of classes and descriptors we might have
aoqi@0 1058 * to work on.
aoqi@0 1059 */
aoqi@0 1060
aoqi@0 1061 ObjectStreamClass currdesc = currentClassDesc;
aoqi@0 1062 Class currclass = currentClass;
aoqi@0 1063
aoqi@0 1064 int spBase = spClass; // current top of stack
aoqi@0 1065
aoqi@0 1066 /* The object's classes should be processed from supertype to subtype
aoqi@0 1067 * Push all the clases of the current object onto a stack.
aoqi@0 1068 * Note that only the serializable classes are represented
aoqi@0 1069 * in the descriptor list.
aoqi@0 1070 *
aoqi@0 1071 * Handle versioning where one or more supertypes of
aoqi@0 1072 * have been inserted or removed. The stack will
aoqi@0 1073 * contain pairs of descriptors and the corresponding
aoqi@0 1074 * class. If the object has a class that did not occur in
aoqi@0 1075 * the original the descriptor will be null. If the
aoqi@0 1076 * original object had a descriptor for a class not
aoqi@0 1077 * present in the local hierarchy of the object the class will be
aoqi@0 1078 * null.
aoqi@0 1079 *
aoqi@0 1080 */
aoqi@0 1081
aoqi@0 1082 /*
aoqi@0 1083 * This is your basic diff pattern, made simpler
aoqi@0 1084 * because reordering is not allowed.
aoqi@0 1085 */
aoqi@0 1086 // sun.4296963 ibm.11861
aoqi@0 1087 // d11861 we should stop when we find the highest serializable class
aoqi@0 1088 // We need this so that when we allocate the new object below, we
aoqi@0 1089 // can call the constructor of the non-serializable superclass.
aoqi@0 1090 // Note that in the JRMP variant of this code the
aoqi@0 1091 // ObjectStreamClass.lookup() method handles this, but we've put
aoqi@0 1092 // this fix here rather than change lookup because the new behaviour
aoqi@0 1093 // is needed in other cases.
aoqi@0 1094
aoqi@0 1095 for (currdesc = currentClassDesc, currclass = currentClass;
aoqi@0 1096 currdesc != null && currdesc.isSerializable(); /*sun.4296963 ibm.11861*/
aoqi@0 1097 currdesc = currdesc.getSuperclass()) {
aoqi@0 1098
aoqi@0 1099 /*
aoqi@0 1100 * Search the classes to see if the class of this
aoqi@0 1101 * descriptor appears further up the hierarchy. Until
aoqi@0 1102 * it's found assume its an inserted class. If it's
aoqi@0 1103 * not found, its the descriptor's class that has been
aoqi@0 1104 * removed.
aoqi@0 1105 */
aoqi@0 1106 Class cc = currdesc.forClass();
aoqi@0 1107 Class cl;
aoqi@0 1108 for (cl = currclass; cl != null; cl = cl.getSuperclass()) {
aoqi@0 1109 if (cc == cl) {
aoqi@0 1110 // found a superclass that matches this descriptor
aoqi@0 1111 break;
aoqi@0 1112 } else {
aoqi@0 1113 /* Ignore a class that doesn't match. No
aoqi@0 1114 * action is needed since it is already
aoqi@0 1115 * initialized.
aoqi@0 1116 */
aoqi@0 1117 }
aoqi@0 1118 } // end : for (cl = currclass; cl != null; cl = cl.getSuperclass())
aoqi@0 1119 /* Test if there is room for this new entry.
aoqi@0 1120 * If not, double the size of the arrays and copy the contents.
aoqi@0 1121 */
aoqi@0 1122 spClass++;
aoqi@0 1123 if (spClass >= classes.length) {
aoqi@0 1124 int newlen = classes.length * 2;
aoqi@0 1125 Class[] newclasses = new Class[newlen];
aoqi@0 1126 ObjectStreamClass[] newclassdesc = new ObjectStreamClass[newlen];
aoqi@0 1127
aoqi@0 1128 System.arraycopy(classes, 0,
aoqi@0 1129 newclasses, 0,
aoqi@0 1130 classes.length);
aoqi@0 1131 System.arraycopy(classdesc, 0,
aoqi@0 1132 newclassdesc, 0,
aoqi@0 1133 classes.length);
aoqi@0 1134
aoqi@0 1135 classes = newclasses;
aoqi@0 1136 classdesc = newclassdesc;
aoqi@0 1137 }
aoqi@0 1138
aoqi@0 1139 if (cl == null) {
aoqi@0 1140 /* Class not found corresponding to this descriptor.
aoqi@0 1141 * Pop off all the extra classes pushed.
aoqi@0 1142 * Push the descriptor and a null class.
aoqi@0 1143 */
aoqi@0 1144 classdesc[spClass] = currdesc;
aoqi@0 1145 classes[spClass] = null;
aoqi@0 1146 } else {
aoqi@0 1147 /* Current class descriptor matches current class.
aoqi@0 1148 * Some classes may have been inserted.
aoqi@0 1149 * Record the match and advance the class, continue
aoqi@0 1150 * with the next descriptor.
aoqi@0 1151 */
aoqi@0 1152 classdesc[spClass] = currdesc;
aoqi@0 1153 classes[spClass] = cl;
aoqi@0 1154 currclass = cl.getSuperclass();
aoqi@0 1155 }
aoqi@0 1156 } // end : for (currdesc = currentClassDesc, currclass = currentClass;
aoqi@0 1157
aoqi@0 1158 /* Allocate a new object. The object is only constructed
aoqi@0 1159 * above the highest serializable class and is set to
aoqi@0 1160 * default values for all more specialized classes.
aoqi@0 1161 */
aoqi@0 1162 try {
aoqi@0 1163 currentObject = (currentClass == null) ?
aoqi@0 1164 null : currentClassDesc.newInstance() ;
aoqi@0 1165
aoqi@0 1166 // Store this object and its beginning position
aoqi@0 1167 // since there might be indirections to it while
aoqi@0 1168 // it's been unmarshalled.
aoqi@0 1169 activeRecursionMgr.addObject(offset, currentObject);
aoqi@0 1170 } catch (InvocationTargetException e) {
aoqi@0 1171 InvalidClassException exc = new InvalidClassException(
aoqi@0 1172 currentClass.getName(),
aoqi@0 1173 "InvocationTargetException accessing no-arg constructor");
aoqi@0 1174 exc.initCause( e ) ;
aoqi@0 1175 throw exc ;
aoqi@0 1176 } catch (UnsupportedOperationException e) {
aoqi@0 1177 InvalidClassException exc = new InvalidClassException(
aoqi@0 1178 currentClass.getName(),
aoqi@0 1179 "UnsupportedOperationException accessing no-arg constructor");
aoqi@0 1180 exc.initCause( e ) ;
aoqi@0 1181 throw exc ;
aoqi@0 1182 } catch (InstantiationException e) {
aoqi@0 1183 InvalidClassException exc = new InvalidClassException(
aoqi@0 1184 currentClass.getName(),
aoqi@0 1185 "InstantiationException accessing no-arg constructor");
aoqi@0 1186 exc.initCause( e ) ;
aoqi@0 1187 throw exc ;
aoqi@0 1188 }
aoqi@0 1189
aoqi@0 1190 /*
aoqi@0 1191 * For all the pushed descriptors and classes.
aoqi@0 1192 * if the class has its own writeObject and readObject methods
aoqi@0 1193 * call the readObject method
aoqi@0 1194 * else
aoqi@0 1195 * invoke the defaultReadObject method
aoqi@0 1196 */
aoqi@0 1197 try {
aoqi@0 1198 for (spClass = spClass; spClass > spBase; spClass--) {
aoqi@0 1199 /*
aoqi@0 1200 * Set current descriptor and corresponding class
aoqi@0 1201 */
aoqi@0 1202 currentClassDesc = classdesc[spClass];
aoqi@0 1203 currentClass = classes[spClass];
aoqi@0 1204 if (classes[spClass] != null) {
aoqi@0 1205 /* Read the data from the stream described by the
aoqi@0 1206 * descriptor and store into the matching class.
aoqi@0 1207 */
aoqi@0 1208
aoqi@0 1209 ReadObjectState oldState = readObjectState;
aoqi@0 1210 setState(DEFAULT_STATE);
aoqi@0 1211
aoqi@0 1212 try {
aoqi@0 1213
aoqi@0 1214 // Changed since invokeObjectReader no longer does this.
aoqi@0 1215 if (currentClassDesc.hasWriteObject()) {
aoqi@0 1216
aoqi@0 1217 // Read format version
aoqi@0 1218 readFormatVersion();
aoqi@0 1219
aoqi@0 1220 // Read defaultWriteObject indicator
aoqi@0 1221 boolean calledDefaultWriteObject = readBoolean();
aoqi@0 1222
aoqi@0 1223 readObjectState.beginUnmarshalCustomValue(this,
aoqi@0 1224 calledDefaultWriteObject,
aoqi@0 1225 (currentClassDesc.readObjectMethod
aoqi@0 1226 != null));
aoqi@0 1227 } else {
aoqi@0 1228 if (currentClassDesc.hasReadObject())
aoqi@0 1229 setState(IN_READ_OBJECT_REMOTE_NOT_CUSTOM_MARSHALED);
aoqi@0 1230 }
aoqi@0 1231
aoqi@0 1232 if (!invokeObjectReader(currentClassDesc, currentObject, currentClass) ||
aoqi@0 1233 readObjectState == IN_READ_OBJECT_DEFAULTS_SENT) {
aoqi@0 1234
aoqi@0 1235 // Error case of no readObject and didn't call
aoqi@0 1236 // defaultWriteObject handled in default state
aoqi@0 1237
aoqi@0 1238 ObjectStreamField[] fields =
aoqi@0 1239 currentClassDesc.getFieldsNoCopy();
aoqi@0 1240 if (fields.length > 0) {
aoqi@0 1241 inputClassFields(currentObject, currentClass, fields, sender);
aoqi@0 1242 }
aoqi@0 1243 }
aoqi@0 1244
aoqi@0 1245 if (currentClassDesc.hasWriteObject())
aoqi@0 1246 readObjectState.endUnmarshalCustomValue(this);
aoqi@0 1247
aoqi@0 1248 } finally {
aoqi@0 1249 setState(oldState);
aoqi@0 1250 }
aoqi@0 1251
aoqi@0 1252 } else {
aoqi@0 1253
aoqi@0 1254 // _REVISIT_ : Can we ever get here?
aoqi@0 1255 /* No local class for this descriptor,
aoqi@0 1256 * Skip over the data for this class.
aoqi@0 1257 * like defaultReadObject with a null currentObject.
aoqi@0 1258 * The code will read the values but discard them.
aoqi@0 1259 */
aoqi@0 1260 ObjectStreamField[] fields =
aoqi@0 1261 currentClassDesc.getFieldsNoCopy();
aoqi@0 1262 if (fields.length > 0) {
aoqi@0 1263 inputClassFields(null, currentClass, fields, sender);
aoqi@0 1264 }
aoqi@0 1265
aoqi@0 1266 }
aoqi@0 1267
aoqi@0 1268 }
aoqi@0 1269 } finally {
aoqi@0 1270 // Make sure we exit at the same stack level as when we started.
aoqi@0 1271 spClass = spBase;
aoqi@0 1272 }
aoqi@0 1273 }
aoqi@0 1274 } finally {
aoqi@0 1275 // We've completed deserializing this object. Any
aoqi@0 1276 // future indirections will be handled correctly at the
aoqi@0 1277 // CDR level. The ActiveRecursionManager only deals with
aoqi@0 1278 // objects currently being deserialized.
aoqi@0 1279 activeRecursionMgr.removeObject(offset);
aoqi@0 1280 }
aoqi@0 1281
aoqi@0 1282 return currentObject;
aoqi@0 1283 }
aoqi@0 1284
aoqi@0 1285 // This retrieves a vector of FVD's for the hierarchy of serializable classes stemming from
aoqi@0 1286 // repositoryID. It is assumed that the sender will not provide base_value id's for non-serializable
aoqi@0 1287 // classes!
aoqi@0 1288 private Vector getOrderedDescriptions(String repositoryID,
aoqi@0 1289 com.sun.org.omg.SendingContext.CodeBase sender) {
aoqi@0 1290 Vector descs = new Vector();
aoqi@0 1291
aoqi@0 1292 if (sender == null) {
aoqi@0 1293 return descs;
aoqi@0 1294 }
aoqi@0 1295
aoqi@0 1296 FullValueDescription aFVD = sender.meta(repositoryID);
aoqi@0 1297 while (aFVD != null) {
aoqi@0 1298 descs.insertElementAt(aFVD, 0);
aoqi@0 1299 if ((aFVD.base_value != null) && !kEmptyStr.equals(aFVD.base_value)) {
aoqi@0 1300 aFVD = sender.meta(aFVD.base_value);
aoqi@0 1301 }
aoqi@0 1302 else return descs;
aoqi@0 1303 }
aoqi@0 1304
aoqi@0 1305 return descs;
aoqi@0 1306 }
aoqi@0 1307
aoqi@0 1308 /**
aoqi@0 1309 * This input method uses FullValueDescriptions retrieved from the sender's runtime to
aoqi@0 1310 * read in the data. This method is capable of throwing out data not applicable to client's fields.
aoqi@0 1311 * This method handles instances where the reader has a class not sent by the sender, the sender sent
aoqi@0 1312 * a class not present on the reader, and/or the reader's class does not match the sender's class.
aoqi@0 1313 *
aoqi@0 1314 * NOTE : If the local description indicates custom marshaling and the remote type's FVD also
aoqi@0 1315 * indicates custom marsahling than the local type is used to read the data off the wire. However,
aoqi@0 1316 * if either says custom while the other does not, a MARSHAL error is thrown. Externalizable is
aoqi@0 1317 * a form of custom marshaling.
aoqi@0 1318 *
aoqi@0 1319 */
aoqi@0 1320 private synchronized Object inputObjectUsingFVD(Class clz,
aoqi@0 1321 String repositoryID,
aoqi@0 1322 com.sun.org.omg.SendingContext.CodeBase sender,
aoqi@0 1323 int offset)
aoqi@0 1324 throws IOException, ClassNotFoundException
aoqi@0 1325 {
aoqi@0 1326 int spBase = spClass; // current top of stack
aoqi@0 1327 try{
aoqi@0 1328
aoqi@0 1329 /*
aoqi@0 1330 * Get the descriptor and then class of the incoming object.
aoqi@0 1331 */
aoqi@0 1332
aoqi@0 1333 ObjectStreamClass currdesc = currentClassDesc = ObjectStreamClass.lookup(clz);
aoqi@0 1334 Class currclass = currentClass = clz;
aoqi@0 1335
aoqi@0 1336 /* If Externalizable,
aoqi@0 1337 * Create an instance and tell it to read its data.
aoqi@0 1338 * else,
aoqi@0 1339 * Handle it as a serializable class.
aoqi@0 1340 */
aoqi@0 1341 if (currentClassDesc.isExternalizable()) {
aoqi@0 1342 try {
aoqi@0 1343 currentObject = (currentClass == null) ?
aoqi@0 1344 null : currentClassDesc.newInstance();
aoqi@0 1345 if (currentObject != null) {
aoqi@0 1346 // Store this object and its beginning position
aoqi@0 1347 // since there might be indirections to it while
aoqi@0 1348 // it's been unmarshalled.
aoqi@0 1349 activeRecursionMgr.addObject(offset, currentObject);
aoqi@0 1350
aoqi@0 1351 // Read format version
aoqi@0 1352 readFormatVersion();
aoqi@0 1353
aoqi@0 1354 Externalizable ext = (Externalizable)currentObject;
aoqi@0 1355 ext.readExternal(this);
aoqi@0 1356 }
aoqi@0 1357 } catch (InvocationTargetException e) {
aoqi@0 1358 InvalidClassException exc = new InvalidClassException(
aoqi@0 1359 currentClass.getName(),
aoqi@0 1360 "InvocationTargetException accessing no-arg constructor");
aoqi@0 1361 exc.initCause( e ) ;
aoqi@0 1362 throw exc ;
aoqi@0 1363 } catch (UnsupportedOperationException e) {
aoqi@0 1364 InvalidClassException exc = new InvalidClassException(
aoqi@0 1365 currentClass.getName(),
aoqi@0 1366 "UnsupportedOperationException accessing no-arg constructor");
aoqi@0 1367 exc.initCause( e ) ;
aoqi@0 1368 throw exc ;
aoqi@0 1369 } catch (InstantiationException e) {
aoqi@0 1370 InvalidClassException exc = new InvalidClassException(
aoqi@0 1371 currentClass.getName(),
aoqi@0 1372 "InstantiationException accessing no-arg constructor");
aoqi@0 1373 exc.initCause( e ) ;
aoqi@0 1374 throw exc ;
aoqi@0 1375 }
aoqi@0 1376 } else {
aoqi@0 1377 /*
aoqi@0 1378 * This is your basic diff pattern, made simpler
aoqi@0 1379 * because reordering is not allowed.
aoqi@0 1380 */
aoqi@0 1381 for (currdesc = currentClassDesc, currclass = currentClass;
aoqi@0 1382 currdesc != null && currdesc.isSerializable(); /*sun.4296963 ibm.11861*/
aoqi@0 1383
aoqi@0 1384 currdesc = currdesc.getSuperclass()) {
aoqi@0 1385
aoqi@0 1386 /*
aoqi@0 1387 * Search the classes to see if the class of this
aoqi@0 1388 * descriptor appears further up the hierarchy. Until
aoqi@0 1389 * it's found assume its an inserted class. If it's
aoqi@0 1390 * not found, its the descriptor's class that has been
aoqi@0 1391 * removed.
aoqi@0 1392 */
aoqi@0 1393 Class cc = currdesc.forClass();
aoqi@0 1394 Class cl;
aoqi@0 1395 for (cl = currclass; cl != null; cl = cl.getSuperclass()) {
aoqi@0 1396 if (cc == cl) {
aoqi@0 1397 // found a superclass that matches this descriptor
aoqi@0 1398 break;
aoqi@0 1399 } else {
aoqi@0 1400 /* Ignore a class that doesn't match. No
aoqi@0 1401 * action is needed since it is already
aoqi@0 1402 * initialized.
aoqi@0 1403 */
aoqi@0 1404 }
aoqi@0 1405 } // end : for (cl = currclass; cl != null; cl = cl.getSuperclass())
aoqi@0 1406 /* Test if there is room for this new entry.
aoqi@0 1407 * If not, double the size of the arrays and copy the contents.
aoqi@0 1408 */
aoqi@0 1409 spClass++;
aoqi@0 1410 if (spClass >= classes.length) {
aoqi@0 1411 int newlen = classes.length * 2;
aoqi@0 1412 Class[] newclasses = new Class[newlen];
aoqi@0 1413 ObjectStreamClass[] newclassdesc = new ObjectStreamClass[newlen];
aoqi@0 1414
aoqi@0 1415 System.arraycopy(classes, 0,
aoqi@0 1416 newclasses, 0,
aoqi@0 1417 classes.length);
aoqi@0 1418 System.arraycopy(classdesc, 0,
aoqi@0 1419 newclassdesc, 0,
aoqi@0 1420 classes.length);
aoqi@0 1421
aoqi@0 1422 classes = newclasses;
aoqi@0 1423 classdesc = newclassdesc;
aoqi@0 1424 }
aoqi@0 1425
aoqi@0 1426 if (cl == null) {
aoqi@0 1427 /* Class not found corresponding to this descriptor.
aoqi@0 1428 * Pop off all the extra classes pushed.
aoqi@0 1429 * Push the descriptor and a null class.
aoqi@0 1430 */
aoqi@0 1431 classdesc[spClass] = currdesc;
aoqi@0 1432 classes[spClass] = null;
aoqi@0 1433 } else {
aoqi@0 1434 /* Current class descriptor matches current class.
aoqi@0 1435 * Some classes may have been inserted.
aoqi@0 1436 * Record the match and advance the class, continue
aoqi@0 1437 * with the next descriptor.
aoqi@0 1438 */
aoqi@0 1439 classdesc[spClass] = currdesc;
aoqi@0 1440 classes[spClass] = cl;
aoqi@0 1441 currclass = cl.getSuperclass();
aoqi@0 1442 }
aoqi@0 1443 } // end : for (currdesc = currentClassDesc, currclass = currentClass;
aoqi@0 1444
aoqi@0 1445 /* Allocate a new object.
aoqi@0 1446 */
aoqi@0 1447 try {
aoqi@0 1448 currentObject = (currentClass == null) ?
aoqi@0 1449 null : currentClassDesc.newInstance();
aoqi@0 1450
aoqi@0 1451 // Store this object and its beginning position
aoqi@0 1452 // since there might be indirections to it while
aoqi@0 1453 // it's been unmarshalled.
aoqi@0 1454 activeRecursionMgr.addObject(offset, currentObject);
aoqi@0 1455 } catch (InvocationTargetException e) {
aoqi@0 1456 InvalidClassException exc = new InvalidClassException(
aoqi@0 1457 currentClass.getName(),
aoqi@0 1458 "InvocationTargetException accessing no-arg constructor");
aoqi@0 1459 exc.initCause( e ) ;
aoqi@0 1460 throw exc ;
aoqi@0 1461 } catch (UnsupportedOperationException e) {
aoqi@0 1462 InvalidClassException exc = new InvalidClassException(
aoqi@0 1463 currentClass.getName(),
aoqi@0 1464 "UnsupportedOperationException accessing no-arg constructor");
aoqi@0 1465 exc.initCause( e ) ;
aoqi@0 1466 throw exc ;
aoqi@0 1467 } catch (InstantiationException e) {
aoqi@0 1468 InvalidClassException exc = new InvalidClassException(
aoqi@0 1469 currentClass.getName(),
aoqi@0 1470 "InstantiationException accessing no-arg constructor");
aoqi@0 1471 exc.initCause( e ) ;
aoqi@0 1472 throw exc ;
aoqi@0 1473 }
aoqi@0 1474
aoqi@0 1475 Enumeration fvdsList = getOrderedDescriptions(repositoryID, sender).elements();
aoqi@0 1476
aoqi@0 1477 while((fvdsList.hasMoreElements()) && (spClass > spBase)) {
aoqi@0 1478 FullValueDescription fvd = (FullValueDescription)fvdsList.nextElement();
aoqi@0 1479 // d4365188: backward compatability
aoqi@0 1480 String repIDForFVD = vhandler.getClassName(fvd.id);
aoqi@0 1481 String repIDForClass = vhandler.getClassName(vhandler.getRMIRepositoryID(currentClass));
aoqi@0 1482
aoqi@0 1483 while ((spClass > spBase) &&
aoqi@0 1484 (!repIDForFVD.equals(repIDForClass))) {
aoqi@0 1485 int pos = findNextClass(repIDForFVD, classes, spClass, spBase);
aoqi@0 1486 if (pos != -1) {
aoqi@0 1487 spClass = pos;
aoqi@0 1488 currclass = currentClass = classes[spClass];
aoqi@0 1489 repIDForClass = vhandler.getClassName(vhandler.getRMIRepositoryID(currentClass));
aoqi@0 1490 }
aoqi@0 1491 else { // Read and throw away one level of the fvdslist
aoqi@0 1492
aoqi@0 1493 // This seems to mean that the sender had a superclass that
aoqi@0 1494 // we don't have
aoqi@0 1495
aoqi@0 1496 if (fvd.is_custom) {
aoqi@0 1497
aoqi@0 1498 readFormatVersion();
aoqi@0 1499 boolean calledDefaultWriteObject = readBoolean();
aoqi@0 1500
aoqi@0 1501 if (calledDefaultWriteObject)
aoqi@0 1502 inputClassFields(null, null, null, fvd.members, sender);
aoqi@0 1503
aoqi@0 1504 if (getStreamFormatVersion() == 2) {
aoqi@0 1505
aoqi@0 1506 ((ValueInputStream)getOrbStream()).start_value();
aoqi@0 1507 ((ValueInputStream)getOrbStream()).end_value();
aoqi@0 1508 }
aoqi@0 1509
aoqi@0 1510 // WARNING: If stream format version is 1 and there's
aoqi@0 1511 // optional data, we'll get some form of exception down
aoqi@0 1512 // the line or data corruption.
aoqi@0 1513
aoqi@0 1514 } else {
aoqi@0 1515
aoqi@0 1516 inputClassFields(null, currentClass, null, fvd.members, sender);
aoqi@0 1517 }
aoqi@0 1518
aoqi@0 1519 if (fvdsList.hasMoreElements()){
aoqi@0 1520 fvd = (FullValueDescription)fvdsList.nextElement();
aoqi@0 1521 repIDForFVD = vhandler.getClassName(fvd.id);
aoqi@0 1522 }
aoqi@0 1523 else return currentObject;
aoqi@0 1524 }
aoqi@0 1525 }
aoqi@0 1526
aoqi@0 1527 currdesc = currentClassDesc = ObjectStreamClass.lookup(currentClass);
aoqi@0 1528
aoqi@0 1529 if (!repIDForClass.equals("java.lang.Object")) {
aoqi@0 1530
aoqi@0 1531 // If the sender used custom marshaling, then it should have put
aoqi@0 1532 // the two bytes on the wire indicating stream format version
aoqi@0 1533 // and whether or not the writeObject method called
aoqi@0 1534 // defaultWriteObject/writeFields.
aoqi@0 1535
aoqi@0 1536 ReadObjectState oldState = readObjectState;
aoqi@0 1537 setState(DEFAULT_STATE);
aoqi@0 1538
aoqi@0 1539 try {
aoqi@0 1540
aoqi@0 1541 if (fvd.is_custom) {
aoqi@0 1542
aoqi@0 1543 // Read format version
aoqi@0 1544 readFormatVersion();
aoqi@0 1545
aoqi@0 1546 // Read defaultWriteObject indicator
aoqi@0 1547 boolean calledDefaultWriteObject = readBoolean();
aoqi@0 1548
aoqi@0 1549 readObjectState.beginUnmarshalCustomValue(this,
aoqi@0 1550 calledDefaultWriteObject,
aoqi@0 1551 (currentClassDesc.readObjectMethod
aoqi@0 1552 != null));
aoqi@0 1553 }
aoqi@0 1554
aoqi@0 1555 boolean usedReadObject = false;
aoqi@0 1556
aoqi@0 1557 // Always use readObject if it exists, and fall back to default
aoqi@0 1558 // unmarshaling if it doesn't.
aoqi@0 1559 try {
aoqi@0 1560
aoqi@0 1561 if (!fvd.is_custom && currentClassDesc.hasReadObject())
aoqi@0 1562 setState(IN_READ_OBJECT_REMOTE_NOT_CUSTOM_MARSHALED);
aoqi@0 1563
aoqi@0 1564 // See the definition of defaultReadObjectFVDMembers
aoqi@0 1565 // for more information. This concerns making sure
aoqi@0 1566 // we use the remote FVD's members in defaultReadObject.
aoqi@0 1567 defaultReadObjectFVDMembers = fvd.members;
aoqi@0 1568 usedReadObject = invokeObjectReader(currentClassDesc,
aoqi@0 1569 currentObject,
aoqi@0 1570 currentClass);
aoqi@0 1571
aoqi@0 1572 } finally {
aoqi@0 1573 defaultReadObjectFVDMembers = null;
aoqi@0 1574 }
aoqi@0 1575
aoqi@0 1576 // Note that the !usedReadObject !calledDefaultWriteObject
aoqi@0 1577 // case is handled by the beginUnmarshalCustomValue method
aoqi@0 1578 // of the default state
aoqi@0 1579 if (!usedReadObject || readObjectState == IN_READ_OBJECT_DEFAULTS_SENT)
aoqi@0 1580 inputClassFields(currentObject, currentClass, currdesc, fvd.members, sender);
aoqi@0 1581
aoqi@0 1582 if (fvd.is_custom)
aoqi@0 1583 readObjectState.endUnmarshalCustomValue(this);
aoqi@0 1584
aoqi@0 1585 } finally {
aoqi@0 1586 setState(oldState);
aoqi@0 1587 }
aoqi@0 1588
aoqi@0 1589 currclass = currentClass = classes[--spClass];
aoqi@0 1590
aoqi@0 1591 } else {
aoqi@0 1592
aoqi@0 1593 // The remaining hierarchy of the local class does not match the sender's FVD.
aoqi@0 1594 // So, use remaining FVDs to read data off wire. If any remaining FVDs indicate
aoqi@0 1595 // custom marshaling, throw MARSHAL error.
aoqi@0 1596 inputClassFields(null, currentClass, null, fvd.members, sender);
aoqi@0 1597
aoqi@0 1598 while (fvdsList.hasMoreElements()){
aoqi@0 1599 fvd = (FullValueDescription)fvdsList.nextElement();
aoqi@0 1600
aoqi@0 1601 if (fvd.is_custom)
aoqi@0 1602 skipCustomUsingFVD(fvd.members, sender);
aoqi@0 1603 else
aoqi@0 1604 inputClassFields(null, currentClass, null, fvd.members, sender);
aoqi@0 1605 }
aoqi@0 1606
aoqi@0 1607 }
aoqi@0 1608
aoqi@0 1609 } // end : while(fvdsList.hasMoreElements())
aoqi@0 1610 while (fvdsList.hasMoreElements()){
aoqi@0 1611
aoqi@0 1612 FullValueDescription fvd = (FullValueDescription)fvdsList.nextElement();
aoqi@0 1613 if (fvd.is_custom)
aoqi@0 1614 skipCustomUsingFVD(fvd.members, sender);
aoqi@0 1615 else
aoqi@0 1616 throwAwayData(fvd.members, sender);
aoqi@0 1617 }
aoqi@0 1618 }
aoqi@0 1619
aoqi@0 1620 return currentObject;
aoqi@0 1621 }
aoqi@0 1622 finally {
aoqi@0 1623 // Make sure we exit at the same stack level as when we started.
aoqi@0 1624 spClass = spBase;
aoqi@0 1625
aoqi@0 1626 // We've completed deserializing this object. Any
aoqi@0 1627 // future indirections will be handled correctly at the
aoqi@0 1628 // CDR level. The ActiveRecursionManager only deals with
aoqi@0 1629 // objects currently being deserialized.
aoqi@0 1630 activeRecursionMgr.removeObject(offset);
aoqi@0 1631 }
aoqi@0 1632
aoqi@0 1633 }
aoqi@0 1634
aoqi@0 1635 /**
aoqi@0 1636 * This input method uses FullValueDescriptions retrieved from the sender's runtime to
aoqi@0 1637 * read in the data. This method is capable of throwing out data not applicable to client's fields.
aoqi@0 1638 *
aoqi@0 1639 * NOTE : If the local description indicates custom marshaling and the remote type's FVD also
aoqi@0 1640 * indicates custom marsahling than the local type is used to read the data off the wire. However,
aoqi@0 1641 * if either says custom while the other does not, a MARSHAL error is thrown. Externalizable is
aoqi@0 1642 * a form of custom marshaling.
aoqi@0 1643 *
aoqi@0 1644 */
aoqi@0 1645 private Object skipObjectUsingFVD(String repositoryID,
aoqi@0 1646 com.sun.org.omg.SendingContext.CodeBase sender)
aoqi@0 1647 throws IOException, ClassNotFoundException
aoqi@0 1648 {
aoqi@0 1649
aoqi@0 1650 Enumeration fvdsList = getOrderedDescriptions(repositoryID, sender).elements();
aoqi@0 1651
aoqi@0 1652 while(fvdsList.hasMoreElements()) {
aoqi@0 1653 FullValueDescription fvd = (FullValueDescription)fvdsList.nextElement();
aoqi@0 1654 String repIDForFVD = vhandler.getClassName(fvd.id);
aoqi@0 1655
aoqi@0 1656 if (!repIDForFVD.equals("java.lang.Object")) {
aoqi@0 1657 if (fvd.is_custom) {
aoqi@0 1658
aoqi@0 1659 readFormatVersion();
aoqi@0 1660
aoqi@0 1661 boolean calledDefaultWriteObject = readBoolean();
aoqi@0 1662
aoqi@0 1663 if (calledDefaultWriteObject)
aoqi@0 1664 inputClassFields(null, null, null, fvd.members, sender);
aoqi@0 1665
aoqi@0 1666 if (getStreamFormatVersion() == 2) {
aoqi@0 1667
aoqi@0 1668 ((ValueInputStream)getOrbStream()).start_value();
aoqi@0 1669 ((ValueInputStream)getOrbStream()).end_value();
aoqi@0 1670 }
aoqi@0 1671
aoqi@0 1672 // WARNING: If stream format version is 1 and there's
aoqi@0 1673 // optional data, we'll get some form of exception down
aoqi@0 1674 // the line.
aoqi@0 1675
aoqi@0 1676 } else {
aoqi@0 1677 // Use default marshaling
aoqi@0 1678 inputClassFields(null, null, null, fvd.members, sender);
aoqi@0 1679 }
aoqi@0 1680 }
aoqi@0 1681
aoqi@0 1682 } // end : while(fvdsList.hasMoreElements())
aoqi@0 1683 return null;
aoqi@0 1684
aoqi@0 1685 }
aoqi@0 1686
aoqi@0 1687 ///////////////////
aoqi@0 1688
aoqi@0 1689 private int findNextClass(String classname, Class classes[], int _spClass, int _spBase){
aoqi@0 1690
aoqi@0 1691 for (int i = _spClass; i > _spBase; i--){
aoqi@0 1692 if (classname.equals(classes[i].getName())) {
aoqi@0 1693 return i;
aoqi@0 1694 }
aoqi@0 1695 }
aoqi@0 1696
aoqi@0 1697 return -1;
aoqi@0 1698 }
aoqi@0 1699
aoqi@0 1700 /*
aoqi@0 1701 * Invoke the readObject method if present. Assumes that in the case of custom
aoqi@0 1702 * marshaling, the format version and defaultWriteObject indicator were already
aoqi@0 1703 * removed.
aoqi@0 1704 */
aoqi@0 1705 private boolean invokeObjectReader(ObjectStreamClass osc, Object obj, Class aclass)
aoqi@0 1706 throws InvalidClassException, StreamCorruptedException,
aoqi@0 1707 ClassNotFoundException, IOException
aoqi@0 1708 {
aoqi@0 1709 if (osc.readObjectMethod == null) {
aoqi@0 1710 return false;
aoqi@0 1711 }
aoqi@0 1712
aoqi@0 1713 try {
aoqi@0 1714 osc.readObjectMethod.invoke( obj, readObjectArgList ) ;
aoqi@0 1715 return true;
aoqi@0 1716 } catch (InvocationTargetException e) {
aoqi@0 1717 Throwable t = e.getTargetException();
aoqi@0 1718 if (t instanceof ClassNotFoundException)
aoqi@0 1719 throw (ClassNotFoundException)t;
aoqi@0 1720 else if (t instanceof IOException)
aoqi@0 1721 throw (IOException)t;
aoqi@0 1722 else if (t instanceof RuntimeException)
aoqi@0 1723 throw (RuntimeException) t;
aoqi@0 1724 else if (t instanceof Error)
aoqi@0 1725 throw (Error) t;
aoqi@0 1726 else
aoqi@0 1727 // XXX I18N, logging needed.
aoqi@0 1728 throw new Error("internal error");
aoqi@0 1729 } catch (IllegalAccessException e) {
aoqi@0 1730 return false;
aoqi@0 1731 }
aoqi@0 1732 }
aoqi@0 1733
aoqi@0 1734 /*
aoqi@0 1735 * Reset the stream to be just like it was after the constructor.
aoqi@0 1736 */
aoqi@0 1737 private void resetStream() throws IOException {
aoqi@0 1738
aoqi@0 1739 if (classes == null)
aoqi@0 1740 classes = new Class[20];
aoqi@0 1741 else {
aoqi@0 1742 for (int i = 0; i < classes.length; i++)
aoqi@0 1743 classes[i] = null;
aoqi@0 1744 }
aoqi@0 1745 if (classdesc == null)
aoqi@0 1746 classdesc = new ObjectStreamClass[20];
aoqi@0 1747 else {
aoqi@0 1748 for (int i = 0; i < classdesc.length; i++)
aoqi@0 1749 classdesc[i] = null;
aoqi@0 1750 }
aoqi@0 1751 spClass = 0;
aoqi@0 1752
aoqi@0 1753 if (callbacks != null)
aoqi@0 1754 callbacks.setSize(0); // discard any pending callbacks
aoqi@0 1755 }
aoqi@0 1756
aoqi@0 1757 /**
aoqi@0 1758 * Factored out of inputClassFields This reads a primitive value and sets it
aoqi@0 1759 * in the field of o described by the ObjectStreamField field.
aoqi@0 1760 *
aoqi@0 1761 * Note that reflection cannot be used here, because reflection cannot be used
aoqi@0 1762 * to set final fields.
aoqi@0 1763 */
aoqi@0 1764 private void inputPrimitiveField(Object o, Class cl, ObjectStreamField field)
aoqi@0 1765 throws InvalidClassException, IOException {
aoqi@0 1766
aoqi@0 1767 try {
aoqi@0 1768 switch (field.getTypeCode()) {
aoqi@0 1769 case 'B':
aoqi@0 1770 byte byteValue = orbStream.read_octet();
msheppar@940 1771 if (field.getField() != null) {
msheppar@940 1772 bridge.putByte( o, field.getFieldID(), byteValue ) ;
msheppar@940 1773 //reflective code: field.getField().setByte( o, byteValue ) ;
msheppar@940 1774 }
aoqi@0 1775 break;
aoqi@0 1776 case 'Z':
aoqi@0 1777 boolean booleanValue = orbStream.read_boolean();
msheppar@940 1778 if (field.getField() != null) {
msheppar@940 1779 bridge.putBoolean( o, field.getFieldID(), booleanValue ) ;
msheppar@940 1780 //reflective code: field.getField().setBoolean( o, booleanValue ) ;
msheppar@940 1781 }
aoqi@0 1782 break;
aoqi@0 1783 case 'C':
aoqi@0 1784 char charValue = orbStream.read_wchar();
msheppar@940 1785 if (field.getField() != null) {
msheppar@940 1786 bridge.putChar( o, field.getFieldID(), charValue ) ;
msheppar@940 1787 //reflective code: field.getField().setChar( o, charValue ) ;
msheppar@940 1788 }
aoqi@0 1789 break;
aoqi@0 1790 case 'S':
aoqi@0 1791 short shortValue = orbStream.read_short();
msheppar@940 1792 if (field.getField() != null) {
msheppar@940 1793 bridge.putShort( o, field.getFieldID(), shortValue ) ;
msheppar@940 1794 //reflective code: field.getField().setShort( o, shortValue ) ;
msheppar@940 1795 }
aoqi@0 1796 break;
aoqi@0 1797 case 'I':
aoqi@0 1798 int intValue = orbStream.read_long();
msheppar@940 1799 if (field.getField() != null) {
msheppar@940 1800 bridge.putInt( o, field.getFieldID(), intValue ) ;
msheppar@940 1801 //reflective code: field.getField().setInt( o, intValue ) ;
msheppar@940 1802 }
aoqi@0 1803 break;
aoqi@0 1804 case 'J':
aoqi@0 1805 long longValue = orbStream.read_longlong();
msheppar@940 1806 if (field.getField() != null) {
msheppar@940 1807 bridge.putLong( o, field.getFieldID(), longValue ) ;
msheppar@940 1808 //reflective code: field.getField().setLong( o, longValue ) ;
msheppar@940 1809 }
aoqi@0 1810 break;
aoqi@0 1811 case 'F' :
aoqi@0 1812 float floatValue = orbStream.read_float();
msheppar@940 1813 if (field.getField() != null) {
msheppar@940 1814 bridge.putFloat( o, field.getFieldID(), floatValue ) ;
msheppar@940 1815 //reflective code: field.getField().setFloat( o, floatValue ) ;
msheppar@940 1816 }
aoqi@0 1817 break;
aoqi@0 1818 case 'D' :
aoqi@0 1819 double doubleValue = orbStream.read_double();
msheppar@940 1820 if (field.getField() != null) {
msheppar@940 1821 bridge.putDouble( o, field.getFieldID(), doubleValue ) ;
msheppar@940 1822 //reflective code: field.getField().setDouble( o, doubleValue ) ;
msheppar@940 1823 }
aoqi@0 1824 break;
aoqi@0 1825 default:
aoqi@0 1826 // XXX I18N, logging needed.
aoqi@0 1827 throw new InvalidClassException(cl.getName());
aoqi@0 1828 }
aoqi@0 1829 } catch (IllegalArgumentException e) {
aoqi@0 1830 /* This case should never happen. If the field types
aoqi@0 1831 are not the same, InvalidClassException is raised when
aoqi@0 1832 matching the local class to the serialized ObjectStreamClass. */
aoqi@0 1833 ClassCastException cce = new ClassCastException("Assigning instance of class " +
aoqi@0 1834 field.getType().getName() +
aoqi@0 1835 " to field " +
aoqi@0 1836 currentClassDesc.getName() + '#' +
aoqi@0 1837 field.getField().getName());
aoqi@0 1838 cce.initCause( e ) ;
aoqi@0 1839 throw cce ;
aoqi@0 1840 }
aoqi@0 1841 }
aoqi@0 1842
aoqi@0 1843 private Object inputObjectField(org.omg.CORBA.ValueMember field,
aoqi@0 1844 com.sun.org.omg.SendingContext.CodeBase sender)
aoqi@0 1845 throws IndirectionException, ClassNotFoundException, IOException,
aoqi@0 1846 StreamCorruptedException {
aoqi@0 1847
aoqi@0 1848 Object objectValue = null;
aoqi@0 1849 Class type = null;
aoqi@0 1850 String id = field.id;
aoqi@0 1851
aoqi@0 1852 try {
aoqi@0 1853 type = vhandler.getClassFromType(id);
aoqi@0 1854 } catch(ClassNotFoundException cnfe) {
aoqi@0 1855 // Make sure type = null
aoqi@0 1856 type = null;
aoqi@0 1857 }
aoqi@0 1858
aoqi@0 1859 String signature = null;
aoqi@0 1860 if (type != null)
aoqi@0 1861 signature = ValueUtility.getSignature(field);
aoqi@0 1862
aoqi@0 1863 if (signature != null && (signature.equals("Ljava/lang/Object;") ||
aoqi@0 1864 signature.equals("Ljava/io/Serializable;") ||
aoqi@0 1865 signature.equals("Ljava/io/Externalizable;"))) {
aoqi@0 1866 objectValue = javax.rmi.CORBA.Util.readAny(orbStream);
aoqi@0 1867 } else {
aoqi@0 1868 // Decide what method call to make based on the type. If
aoqi@0 1869 // it is a type for which we need to load a stub, convert
aoqi@0 1870 // the type to the correct stub type.
aoqi@0 1871 //
aoqi@0 1872 // NOTE : Since FullValueDescription does not allow us
aoqi@0 1873 // to ask whether something is an interface we do not
aoqi@0 1874 // have the ability to optimize this check.
aoqi@0 1875
aoqi@0 1876 int callType = ValueHandlerImpl.kValueType;
aoqi@0 1877
aoqi@0 1878 if (!vhandler.isSequence(id)) {
aoqi@0 1879
aoqi@0 1880 if (field.type.kind().value() == kRemoteTypeCode.kind().value()) {
aoqi@0 1881
aoqi@0 1882 // RMI Object reference...
aoqi@0 1883 callType = ValueHandlerImpl.kRemoteType;
aoqi@0 1884
aoqi@0 1885 } else {
aoqi@0 1886
aoqi@0 1887 // REVISIT. If we don't have the local class,
aoqi@0 1888 // we should probably verify that it's an RMI type,
aoqi@0 1889 // query the remote FVD, and use is_abstract.
aoqi@0 1890 // Our FVD seems to get NullPointerExceptions for any
aoqi@0 1891 // non-RMI types.
aoqi@0 1892
aoqi@0 1893 // This uses the local class in the same way as
aoqi@0 1894 // inputObjectField(ObjectStreamField) does. REVISIT
aoqi@0 1895 // inputObjectField(ObjectStreamField)'s loadStubClass
aoqi@0 1896 // logic. Assumption is that the given type cannot
aoqi@0 1897 // evolve to become a CORBA abstract interface or
aoqi@0 1898 // a RMI abstract interface.
aoqi@0 1899
aoqi@0 1900 if (type != null && type.isInterface() &&
aoqi@0 1901 (vhandler.isAbstractBase(type) ||
aoqi@0 1902 ObjectStreamClassCorbaExt.isAbstractInterface(type))) {
aoqi@0 1903
aoqi@0 1904 callType = ValueHandlerImpl.kAbstractType;
aoqi@0 1905 }
aoqi@0 1906 }
aoqi@0 1907 }
aoqi@0 1908
aoqi@0 1909 // Now that we have used the FVD of the field to determine the proper course
aoqi@0 1910 // of action, it is ok to use the type (Class) from this point forward since
aoqi@0 1911 // the rep. id for this read will also follow on the wire.
aoqi@0 1912
aoqi@0 1913 switch (callType) {
aoqi@0 1914 case ValueHandlerImpl.kRemoteType:
aoqi@0 1915 if (type != null)
aoqi@0 1916 objectValue = Utility.readObjectAndNarrow(orbStream, type);
aoqi@0 1917 else
aoqi@0 1918 objectValue = orbStream.read_Object();
aoqi@0 1919 break;
aoqi@0 1920 case ValueHandlerImpl.kAbstractType:
aoqi@0 1921 if (type != null)
aoqi@0 1922 objectValue = Utility.readAbstractAndNarrow(orbStream, type);
aoqi@0 1923 else
aoqi@0 1924 objectValue = orbStream.read_abstract_interface();
aoqi@0 1925 break;
aoqi@0 1926 case ValueHandlerImpl.kValueType:
aoqi@0 1927 if (type != null)
aoqi@0 1928 objectValue = orbStream.read_value(type);
aoqi@0 1929 else
aoqi@0 1930 objectValue = orbStream.read_value();
aoqi@0 1931 break;
aoqi@0 1932 default:
aoqi@0 1933 // XXX I18N, logging needed.
aoqi@0 1934 throw new StreamCorruptedException("Unknown callType: " + callType);
aoqi@0 1935 }
aoqi@0 1936 }
aoqi@0 1937
aoqi@0 1938 return objectValue;
aoqi@0 1939 }
aoqi@0 1940
aoqi@0 1941 /**
aoqi@0 1942 * Factored out of inputClassFields and reused in
aoqi@0 1943 * inputCurrentClassFieldsForReadFields.
aoqi@0 1944 *
aoqi@0 1945 * Reads the field (which of an Object type as opposed to a primitive)
aoqi@0 1946 * described by ObjectStreamField field and returns it.
aoqi@0 1947 */
aoqi@0 1948 private Object inputObjectField(ObjectStreamField field)
aoqi@0 1949 throws InvalidClassException, StreamCorruptedException,
aoqi@0 1950 ClassNotFoundException, IndirectionException, IOException {
aoqi@0 1951
aoqi@0 1952 if (ObjectStreamClassCorbaExt.isAny(field.getTypeString())) {
aoqi@0 1953 return javax.rmi.CORBA.Util.readAny(orbStream);
aoqi@0 1954 }
aoqi@0 1955
aoqi@0 1956 Object objectValue = null;
aoqi@0 1957
aoqi@0 1958 // fields have an API to provide the actual class
aoqi@0 1959 // corresponding to the data type
aoqi@0 1960 // Class type = osc.forClass();
aoqi@0 1961 Class fieldType = field.getType();
aoqi@0 1962 Class actualType = fieldType; // This may change if stub loaded.
aoqi@0 1963
aoqi@0 1964 // Decide what method call to make based on the fieldType. If
aoqi@0 1965 // it is a type for which we need to load a stub, convert
aoqi@0 1966 // the type to the correct stub type.
aoqi@0 1967
aoqi@0 1968 int callType = ValueHandlerImpl.kValueType;
aoqi@0 1969 boolean narrow = false;
aoqi@0 1970
aoqi@0 1971 if (fieldType.isInterface()) {
aoqi@0 1972 boolean loadStubClass = false;
aoqi@0 1973
aoqi@0 1974 if (java.rmi.Remote.class.isAssignableFrom(fieldType)) {
aoqi@0 1975
aoqi@0 1976 // RMI Object reference...
aoqi@0 1977 callType = ValueHandlerImpl.kRemoteType;
aoqi@0 1978
aoqi@0 1979 } else if (org.omg.CORBA.Object.class.isAssignableFrom(fieldType)){
aoqi@0 1980
aoqi@0 1981 // IDL Object reference...
aoqi@0 1982 callType = ValueHandlerImpl.kRemoteType;
aoqi@0 1983 loadStubClass = true;
aoqi@0 1984
aoqi@0 1985 } else if (vhandler.isAbstractBase(fieldType)) {
aoqi@0 1986 // IDL Abstract Object reference...
aoqi@0 1987
aoqi@0 1988 callType = ValueHandlerImpl.kAbstractType;
aoqi@0 1989 loadStubClass = true;
aoqi@0 1990 } else if (ObjectStreamClassCorbaExt.isAbstractInterface(fieldType)) {
aoqi@0 1991 // RMI Abstract Object reference...
aoqi@0 1992
aoqi@0 1993 callType = ValueHandlerImpl.kAbstractType;
aoqi@0 1994 }
aoqi@0 1995
aoqi@0 1996 if (loadStubClass) {
aoqi@0 1997 try {
aoqi@0 1998 String codebase = Util.getCodebase(fieldType);
aoqi@0 1999 String repID = vhandler.createForAnyType(fieldType);
aoqi@0 2000 Class stubType =
aoqi@0 2001 Utility.loadStubClass(repID, codebase, fieldType);
aoqi@0 2002 actualType = stubType;
aoqi@0 2003 } catch (ClassNotFoundException e) {
aoqi@0 2004 narrow = true;
aoqi@0 2005 }
aoqi@0 2006 } else {
aoqi@0 2007 narrow = true;
aoqi@0 2008 }
aoqi@0 2009 }
aoqi@0 2010
aoqi@0 2011 switch (callType) {
aoqi@0 2012 case ValueHandlerImpl.kRemoteType:
aoqi@0 2013 if (!narrow)
aoqi@0 2014 objectValue = (Object)orbStream.read_Object(actualType);
aoqi@0 2015 else
aoqi@0 2016 objectValue = Utility.readObjectAndNarrow(orbStream, actualType);
aoqi@0 2017 break;
aoqi@0 2018 case ValueHandlerImpl.kAbstractType:
aoqi@0 2019 if (!narrow)
aoqi@0 2020 objectValue = (Object)orbStream.read_abstract_interface(actualType);
aoqi@0 2021 else
aoqi@0 2022 objectValue = Utility.readAbstractAndNarrow(orbStream, actualType);
aoqi@0 2023 break;
aoqi@0 2024 case ValueHandlerImpl.kValueType:
aoqi@0 2025 objectValue = (Object)orbStream.read_value(actualType);
aoqi@0 2026 break;
aoqi@0 2027 default:
aoqi@0 2028 // XXX I18N, logging needed.
aoqi@0 2029 throw new StreamCorruptedException("Unknown callType: " + callType);
aoqi@0 2030 }
aoqi@0 2031
aoqi@0 2032 return objectValue;
aoqi@0 2033 }
aoqi@0 2034
aoqi@0 2035 private final boolean mustUseRemoteValueMembers() {
aoqi@0 2036 return defaultReadObjectFVDMembers != null;
aoqi@0 2037 }
aoqi@0 2038
aoqi@0 2039 void readFields(java.util.Map fieldToValueMap)
aoqi@0 2040 throws InvalidClassException, StreamCorruptedException,
aoqi@0 2041 ClassNotFoundException, IOException {
aoqi@0 2042
aoqi@0 2043 if (mustUseRemoteValueMembers()) {
aoqi@0 2044 inputRemoteMembersForReadFields(fieldToValueMap);
aoqi@0 2045 } else
aoqi@0 2046 inputCurrentClassFieldsForReadFields(fieldToValueMap);
aoqi@0 2047 }
aoqi@0 2048
aoqi@0 2049 private final void inputRemoteMembersForReadFields(java.util.Map fieldToValueMap)
aoqi@0 2050 throws InvalidClassException, StreamCorruptedException,
aoqi@0 2051 ClassNotFoundException, IOException {
aoqi@0 2052
aoqi@0 2053 // Must have this local variable since defaultReadObjectFVDMembers
aoqi@0 2054 // may get mangled by recursion.
aoqi@0 2055 ValueMember fields[] = defaultReadObjectFVDMembers;
aoqi@0 2056
aoqi@0 2057 try {
aoqi@0 2058
aoqi@0 2059 for (int i = 0; i < fields.length; i++) {
aoqi@0 2060
aoqi@0 2061 switch (fields[i].type.kind().value()) {
aoqi@0 2062
aoqi@0 2063 case TCKind._tk_octet:
aoqi@0 2064 byte byteValue = orbStream.read_octet();
aoqi@0 2065 fieldToValueMap.put(fields[i].name, new Byte(byteValue));
aoqi@0 2066 break;
aoqi@0 2067 case TCKind._tk_boolean:
aoqi@0 2068 boolean booleanValue = orbStream.read_boolean();
aoqi@0 2069 fieldToValueMap.put(fields[i].name, new Boolean(booleanValue));
aoqi@0 2070 break;
aoqi@0 2071 case TCKind._tk_char:
aoqi@0 2072 // Backwards compatibility. Older Sun ORBs sent
aoqi@0 2073 // _tk_char even though they read and wrote wchars
aoqi@0 2074 // correctly.
aoqi@0 2075 //
aoqi@0 2076 // Fall through to the _tk_wchar case.
aoqi@0 2077 case TCKind._tk_wchar:
aoqi@0 2078 char charValue = orbStream.read_wchar();
aoqi@0 2079 fieldToValueMap.put(fields[i].name, new Character(charValue));
aoqi@0 2080 break;
aoqi@0 2081 case TCKind._tk_short:
aoqi@0 2082 short shortValue = orbStream.read_short();
aoqi@0 2083 fieldToValueMap.put(fields[i].name, new Short(shortValue));
aoqi@0 2084 break;
aoqi@0 2085 case TCKind._tk_long:
aoqi@0 2086 int intValue = orbStream.read_long();
aoqi@0 2087 fieldToValueMap.put(fields[i].name, new Integer(intValue));
aoqi@0 2088 break;
aoqi@0 2089 case TCKind._tk_longlong:
aoqi@0 2090 long longValue = orbStream.read_longlong();
aoqi@0 2091 fieldToValueMap.put(fields[i].name, new Long(longValue));
aoqi@0 2092 break;
aoqi@0 2093 case TCKind._tk_float:
aoqi@0 2094 float floatValue = orbStream.read_float();
aoqi@0 2095 fieldToValueMap.put(fields[i].name, new Float(floatValue));
aoqi@0 2096 break;
aoqi@0 2097 case TCKind._tk_double:
aoqi@0 2098 double doubleValue = orbStream.read_double();
aoqi@0 2099 fieldToValueMap.put(fields[i].name, new Double(doubleValue));
aoqi@0 2100 break;
aoqi@0 2101 case TCKind._tk_value:
aoqi@0 2102 case TCKind._tk_objref:
aoqi@0 2103 case TCKind._tk_value_box:
aoqi@0 2104 Object objectValue = null;
aoqi@0 2105 try {
aoqi@0 2106 objectValue = inputObjectField(fields[i],
aoqi@0 2107 cbSender);
aoqi@0 2108
aoqi@0 2109 } catch (IndirectionException cdrie) {
aoqi@0 2110 // The CDR stream had never seen the given offset before,
aoqi@0 2111 // so check the recursion manager (it will throw an
aoqi@0 2112 // IOException if it doesn't have a reference, either).
aoqi@0 2113 objectValue = activeRecursionMgr.getObject(cdrie.offset);
aoqi@0 2114 }
aoqi@0 2115
aoqi@0 2116 fieldToValueMap.put(fields[i].name, objectValue);
aoqi@0 2117 break;
aoqi@0 2118 default:
aoqi@0 2119 // XXX I18N, logging needed.
aoqi@0 2120 throw new StreamCorruptedException("Unknown kind: "
aoqi@0 2121 + fields[i].type.kind().value());
aoqi@0 2122 }
aoqi@0 2123 }
aoqi@0 2124 } catch (Throwable t) {
aoqi@0 2125 StreamCorruptedException result = new StreamCorruptedException(t.getMessage());
aoqi@0 2126 result.initCause(t);
aoqi@0 2127 throw result;
aoqi@0 2128 }
aoqi@0 2129 }
aoqi@0 2130
aoqi@0 2131 /**
aoqi@0 2132 * Called from InputStreamHook.
aoqi@0 2133 *
aoqi@0 2134 * Reads the fields of the current class (could be the ones
aoqi@0 2135 * queried from the remote FVD) and puts them in
aoqi@0 2136 * the given Map, name to value. Wraps primitives in the
aoqi@0 2137 * corresponding java.lang Objects.
aoqi@0 2138 */
aoqi@0 2139 private final void inputCurrentClassFieldsForReadFields(java.util.Map fieldToValueMap)
aoqi@0 2140 throws InvalidClassException, StreamCorruptedException,
aoqi@0 2141 ClassNotFoundException, IOException {
aoqi@0 2142
aoqi@0 2143 ObjectStreamField[] fields = currentClassDesc.getFieldsNoCopy();
aoqi@0 2144
aoqi@0 2145 int primFields = fields.length - currentClassDesc.objFields;
aoqi@0 2146
aoqi@0 2147 // Handle the primitives first
aoqi@0 2148 for (int i = 0; i < primFields; ++i) {
aoqi@0 2149
aoqi@0 2150 switch (fields[i].getTypeCode()) {
aoqi@0 2151 case 'B':
aoqi@0 2152 byte byteValue = orbStream.read_octet();
aoqi@0 2153 fieldToValueMap.put(fields[i].getName(),
aoqi@0 2154 new Byte(byteValue));
aoqi@0 2155 break;
aoqi@0 2156 case 'Z':
aoqi@0 2157 boolean booleanValue = orbStream.read_boolean();
aoqi@0 2158 fieldToValueMap.put(fields[i].getName(),
aoqi@0 2159 new Boolean(booleanValue));
aoqi@0 2160 break;
aoqi@0 2161 case 'C':
aoqi@0 2162 char charValue = orbStream.read_wchar();
aoqi@0 2163 fieldToValueMap.put(fields[i].getName(),
aoqi@0 2164 new Character(charValue));
aoqi@0 2165 break;
aoqi@0 2166 case 'S':
aoqi@0 2167 short shortValue = orbStream.read_short();
aoqi@0 2168 fieldToValueMap.put(fields[i].getName(),
aoqi@0 2169 new Short(shortValue));
aoqi@0 2170 break;
aoqi@0 2171 case 'I':
aoqi@0 2172 int intValue = orbStream.read_long();
aoqi@0 2173 fieldToValueMap.put(fields[i].getName(),
aoqi@0 2174 new Integer(intValue));
aoqi@0 2175 break;
aoqi@0 2176 case 'J':
aoqi@0 2177 long longValue = orbStream.read_longlong();
aoqi@0 2178 fieldToValueMap.put(fields[i].getName(),
aoqi@0 2179 new Long(longValue));
aoqi@0 2180 break;
aoqi@0 2181 case 'F' :
aoqi@0 2182 float floatValue = orbStream.read_float();
aoqi@0 2183 fieldToValueMap.put(fields[i].getName(),
aoqi@0 2184 new Float(floatValue));
aoqi@0 2185 break;
aoqi@0 2186 case 'D' :
aoqi@0 2187 double doubleValue = orbStream.read_double();
aoqi@0 2188 fieldToValueMap.put(fields[i].getName(),
aoqi@0 2189 new Double(doubleValue));
aoqi@0 2190 break;
aoqi@0 2191 default:
aoqi@0 2192 // XXX I18N, logging needed.
aoqi@0 2193 throw new InvalidClassException(currentClassDesc.getName());
aoqi@0 2194 }
aoqi@0 2195 }
aoqi@0 2196
aoqi@0 2197 /* Read and set object fields from the input stream. */
aoqi@0 2198 if (currentClassDesc.objFields > 0) {
aoqi@0 2199 for (int i = primFields; i < fields.length; i++) {
aoqi@0 2200 Object objectValue = null;
aoqi@0 2201 try {
aoqi@0 2202 objectValue = inputObjectField(fields[i]);
aoqi@0 2203 } catch(IndirectionException cdrie) {
aoqi@0 2204 // The CDR stream had never seen the given offset before,
aoqi@0 2205 // so check the recursion manager (it will throw an
aoqi@0 2206 // IOException if it doesn't have a reference, either).
aoqi@0 2207 objectValue = activeRecursionMgr.getObject(cdrie.offset);
aoqi@0 2208 }
aoqi@0 2209
aoqi@0 2210 fieldToValueMap.put(fields[i].getName(), objectValue);
aoqi@0 2211 }
aoqi@0 2212 }
aoqi@0 2213 }
aoqi@0 2214
aoqi@0 2215 /*
aoqi@0 2216 * Read the fields of the specified class from the input stream and set
aoqi@0 2217 * the values of the fields in the specified object. If the specified
aoqi@0 2218 * object is null, just consume the fields without setting any values. If
aoqi@0 2219 * any ObjectStreamField does not have a reflected Field, don't try to set
aoqi@0 2220 * that field in the object.
aoqi@0 2221 *
aoqi@0 2222 * REVISIT -- This code doesn't do what the comment says to when
aoqi@0 2223 * getField() is null!
aoqi@0 2224 */
aoqi@0 2225 private void inputClassFields(Object o, Class cl,
aoqi@0 2226 ObjectStreamField[] fields,
aoqi@0 2227 com.sun.org.omg.SendingContext.CodeBase sender)
aoqi@0 2228 throws InvalidClassException, StreamCorruptedException,
aoqi@0 2229 ClassNotFoundException, IOException
aoqi@0 2230 {
aoqi@0 2231
aoqi@0 2232 int primFields = fields.length - currentClassDesc.objFields;
aoqi@0 2233
aoqi@0 2234 if (o != null) {
aoqi@0 2235 for (int i = 0; i < primFields; ++i) {
aoqi@0 2236 inputPrimitiveField(o, cl, fields[i]);
aoqi@0 2237 }
aoqi@0 2238 }
aoqi@0 2239
aoqi@0 2240 /* Read and set object fields from the input stream. */
aoqi@0 2241 if (currentClassDesc.objFields > 0) {
aoqi@0 2242 for (int i = primFields; i < fields.length; i++) {
aoqi@0 2243 Object objectValue = null;
aoqi@0 2244
aoqi@0 2245 try {
aoqi@0 2246 objectValue = inputObjectField(fields[i]);
aoqi@0 2247 } catch(IndirectionException cdrie) {
aoqi@0 2248 // The CDR stream had never seen the given offset before,
aoqi@0 2249 // so check the recursion manager (it will throw an
aoqi@0 2250 // IOException if it doesn't have a reference, either).
aoqi@0 2251 objectValue = activeRecursionMgr.getObject(cdrie.offset);
aoqi@0 2252 }
aoqi@0 2253
aoqi@0 2254 if ((o == null) || (fields[i].getField() == null)) {
aoqi@0 2255 continue;
aoqi@0 2256 }
aoqi@0 2257
aoqi@0 2258 try {
aoqi@0 2259 Class fieldCl = fields[i].getClazz();
aoqi@0 2260 if (objectValue != null && !fieldCl.isInstance(objectValue)) {
aoqi@0 2261 throw new IllegalArgumentException();
aoqi@0 2262 }
aoqi@0 2263 bridge.putObject( o, fields[i].getFieldID(), objectValue ) ;
aoqi@0 2264 // reflective code: fields[i].getField().set( o, objectValue ) ;
aoqi@0 2265 } catch (IllegalArgumentException e) {
aoqi@0 2266 ClassCastException exc = new ClassCastException("Assigning instance of class " +
aoqi@0 2267 objectValue.getClass().getName() +
aoqi@0 2268 " to field " +
aoqi@0 2269 currentClassDesc.getName() +
aoqi@0 2270 '#' +
aoqi@0 2271 fields[i].getField().getName());
aoqi@0 2272 exc.initCause( e ) ;
aoqi@0 2273 throw exc ;
aoqi@0 2274 }
aoqi@0 2275 } // end : for loop
aoqi@0 2276 }
aoqi@0 2277 }
aoqi@0 2278
aoqi@0 2279 /*
aoqi@0 2280 * Read the fields of the specified class from the input stream and set
aoqi@0 2281 * the values of the fields in the specified object. If the specified
aoqi@0 2282 * object is null, just consume the fields without setting any values. If
aoqi@0 2283 * any ObjectStreamField does not have a reflected Field, don't try to set
aoqi@0 2284 * that field in the object.
aoqi@0 2285 */
aoqi@0 2286 private void inputClassFields(Object o, Class cl,
aoqi@0 2287 ObjectStreamClass osc,
aoqi@0 2288 ValueMember[] fields,
aoqi@0 2289 com.sun.org.omg.SendingContext.CodeBase sender)
aoqi@0 2290 throws InvalidClassException, StreamCorruptedException,
aoqi@0 2291 ClassNotFoundException, IOException
aoqi@0 2292 {
aoqi@0 2293 try{
aoqi@0 2294 for (int i = 0; i < fields.length; ++i) {
aoqi@0 2295 try {
aoqi@0 2296 switch (fields[i].type.kind().value()) {
aoqi@0 2297 case TCKind._tk_octet:
aoqi@0 2298 byte byteValue = orbStream.read_octet();
aoqi@0 2299 if ((o != null) && osc.hasField(fields[i]))
aoqi@0 2300 setByteField(o, cl, fields[i].name, byteValue);
aoqi@0 2301 break;
aoqi@0 2302 case TCKind._tk_boolean:
aoqi@0 2303 boolean booleanValue = orbStream.read_boolean();
aoqi@0 2304 if ((o != null) && osc.hasField(fields[i]))
aoqi@0 2305 setBooleanField(o, cl, fields[i].name, booleanValue);
aoqi@0 2306 break;
aoqi@0 2307 case TCKind._tk_char:
aoqi@0 2308 // Backwards compatibility. Older Sun ORBs sent
aoqi@0 2309 // _tk_char even though they read and wrote wchars
aoqi@0 2310 // correctly.
aoqi@0 2311 //
aoqi@0 2312 // Fall through to the _tk_wchar case.
aoqi@0 2313 case TCKind._tk_wchar:
aoqi@0 2314 char charValue = orbStream.read_wchar();
aoqi@0 2315 if ((o != null) && osc.hasField(fields[i]))
aoqi@0 2316 setCharField(o, cl, fields[i].name, charValue);
aoqi@0 2317 break;
aoqi@0 2318 case TCKind._tk_short:
aoqi@0 2319 short shortValue = orbStream.read_short();
aoqi@0 2320 if ((o != null) && osc.hasField(fields[i]))
aoqi@0 2321 setShortField(o, cl, fields[i].name, shortValue);
aoqi@0 2322 break;
aoqi@0 2323 case TCKind._tk_long:
aoqi@0 2324 int intValue = orbStream.read_long();
aoqi@0 2325 if ((o != null) && osc.hasField(fields[i]))
aoqi@0 2326 setIntField(o, cl, fields[i].name, intValue);
aoqi@0 2327 break;
aoqi@0 2328 case TCKind._tk_longlong:
aoqi@0 2329 long longValue = orbStream.read_longlong();
aoqi@0 2330 if ((o != null) && osc.hasField(fields[i]))
aoqi@0 2331 setLongField(o, cl, fields[i].name, longValue);
aoqi@0 2332 break;
aoqi@0 2333 case TCKind._tk_float:
aoqi@0 2334 float floatValue = orbStream.read_float();
aoqi@0 2335 if ((o != null) && osc.hasField(fields[i]))
aoqi@0 2336 setFloatField(o, cl, fields[i].name, floatValue);
aoqi@0 2337 break;
aoqi@0 2338 case TCKind._tk_double:
aoqi@0 2339 double doubleValue = orbStream.read_double();
aoqi@0 2340 if ((o != null) && osc.hasField(fields[i]))
aoqi@0 2341 setDoubleField(o, cl, fields[i].name, doubleValue);
aoqi@0 2342 break;
aoqi@0 2343 case TCKind._tk_value:
aoqi@0 2344 case TCKind._tk_objref:
aoqi@0 2345 case TCKind._tk_value_box:
aoqi@0 2346 Object objectValue = null;
aoqi@0 2347 try {
aoqi@0 2348 objectValue = inputObjectField(fields[i], sender);
aoqi@0 2349 } catch (IndirectionException cdrie) {
aoqi@0 2350 // The CDR stream had never seen the given offset before,
aoqi@0 2351 // so check the recursion manager (it will throw an
aoqi@0 2352 // IOException if it doesn't have a reference, either).
aoqi@0 2353 objectValue = activeRecursionMgr.getObject(cdrie.offset);
aoqi@0 2354 }
aoqi@0 2355
aoqi@0 2356 if (o == null)
aoqi@0 2357 continue;
aoqi@0 2358 try {
aoqi@0 2359 if (osc.hasField(fields[i])){
aoqi@0 2360 setObjectField(o,
aoqi@0 2361 cl,
aoqi@0 2362 fields[i].name,
aoqi@0 2363 objectValue);
aoqi@0 2364 } else {
aoqi@0 2365 // REVISIT. Convert to a log message.
aoqi@0 2366 // This is a normal case when fields have
aoqi@0 2367 // been added as part of evolution, but
aoqi@0 2368 // silently skipping can make it hard to
aoqi@0 2369 // debug if there's an error
aoqi@0 2370 // System.out.println("**** warning, not setting field: "
aoqi@0 2371 // + fields[i].name
aoqi@0 2372 // + " since not on class "
aoqi@0 2373 // + osc.getName());
aoqi@0 2374
aoqi@0 2375 }
aoqi@0 2376 } catch (IllegalArgumentException e) {
aoqi@0 2377 // XXX I18N, logging needed.
aoqi@0 2378 ClassCastException cce = new ClassCastException("Assigning instance of class " +
aoqi@0 2379 objectValue.getClass().getName() + " to field " + fields[i].name);
aoqi@0 2380 cce.initCause(e) ;
aoqi@0 2381 throw cce ;
aoqi@0 2382 }
aoqi@0 2383 break;
aoqi@0 2384 default:
aoqi@0 2385 // XXX I18N, logging needed.
aoqi@0 2386 throw new StreamCorruptedException("Unknown kind: "
aoqi@0 2387 + fields[i].type.kind().value());
aoqi@0 2388 }
aoqi@0 2389 } catch (IllegalArgumentException e) {
aoqi@0 2390 /* This case should never happen. If the field types
aoqi@0 2391 are not the same, InvalidClassException is raised when
aoqi@0 2392 matching the local class to the serialized ObjectStreamClass. */
aoqi@0 2393 // XXX I18N, logging needed.
aoqi@0 2394 ClassCastException cce = new ClassCastException("Assigning instance of class " + fields[i].id +
aoqi@0 2395 " to field " + currentClassDesc.getName() + '#' + fields[i].name);
aoqi@0 2396 cce.initCause( e ) ;
aoqi@0 2397 throw cce ;
aoqi@0 2398 }
aoqi@0 2399 }
aoqi@0 2400 } catch(Throwable t){
aoqi@0 2401 // XXX I18N, logging needed.
aoqi@0 2402 StreamCorruptedException sce = new StreamCorruptedException(t.getMessage());
aoqi@0 2403 sce.initCause(t) ;
aoqi@0 2404 throw sce ;
aoqi@0 2405 }
aoqi@0 2406 }
aoqi@0 2407
aoqi@0 2408 private void skipCustomUsingFVD(ValueMember[] fields,
aoqi@0 2409 com.sun.org.omg.SendingContext.CodeBase sender)
aoqi@0 2410 throws InvalidClassException, StreamCorruptedException,
aoqi@0 2411 ClassNotFoundException, IOException
aoqi@0 2412 {
aoqi@0 2413 readFormatVersion();
aoqi@0 2414 boolean calledDefaultWriteObject = readBoolean();
aoqi@0 2415
aoqi@0 2416 if (calledDefaultWriteObject)
aoqi@0 2417 throwAwayData(fields, sender);
aoqi@0 2418
aoqi@0 2419 if (getStreamFormatVersion() == 2) {
aoqi@0 2420
aoqi@0 2421 ((ValueInputStream)getOrbStream()).start_value();
aoqi@0 2422 ((ValueInputStream)getOrbStream()).end_value();
aoqi@0 2423 }
aoqi@0 2424 }
aoqi@0 2425
aoqi@0 2426 /*
aoqi@0 2427 * Read the fields of the specified class from the input stream throw data away.
aoqi@0 2428 * This must handle same switch logic as above.
aoqi@0 2429 */
aoqi@0 2430 private void throwAwayData(ValueMember[] fields,
aoqi@0 2431 com.sun.org.omg.SendingContext.CodeBase sender)
aoqi@0 2432 throws InvalidClassException, StreamCorruptedException,
msheppar@984 2433 ClassNotFoundException, IOException {
msheppar@984 2434
aoqi@0 2435 for (int i = 0; i < fields.length; ++i) {
aoqi@0 2436
aoqi@0 2437 try {
aoqi@0 2438
aoqi@0 2439 switch (fields[i].type.kind().value()) {
aoqi@0 2440 case TCKind._tk_octet:
aoqi@0 2441 orbStream.read_octet();
aoqi@0 2442 break;
aoqi@0 2443 case TCKind._tk_boolean:
aoqi@0 2444 orbStream.read_boolean();
aoqi@0 2445 break;
aoqi@0 2446 case TCKind._tk_char:
aoqi@0 2447 // Backwards compatibility. Older Sun ORBs sent
aoqi@0 2448 // _tk_char even though they read and wrote wchars
aoqi@0 2449 // correctly.
aoqi@0 2450 //
aoqi@0 2451 // Fall through to the _tk_wchar case.
aoqi@0 2452 case TCKind._tk_wchar:
aoqi@0 2453 orbStream.read_wchar();
aoqi@0 2454 break;
aoqi@0 2455 case TCKind._tk_short:
aoqi@0 2456 orbStream.read_short();
aoqi@0 2457 break;
aoqi@0 2458 case TCKind._tk_long:
aoqi@0 2459 orbStream.read_long();
aoqi@0 2460 break;
aoqi@0 2461 case TCKind._tk_longlong:
aoqi@0 2462 orbStream.read_longlong();
aoqi@0 2463 break;
aoqi@0 2464 case TCKind._tk_float:
aoqi@0 2465 orbStream.read_float();
aoqi@0 2466 break;
aoqi@0 2467 case TCKind._tk_double:
aoqi@0 2468 orbStream.read_double();
aoqi@0 2469 break;
aoqi@0 2470 case TCKind._tk_value:
aoqi@0 2471 case TCKind._tk_objref:
aoqi@0 2472 case TCKind._tk_value_box:
aoqi@0 2473 Class type = null;
aoqi@0 2474 String id = fields[i].id;
aoqi@0 2475
aoqi@0 2476 try {
aoqi@0 2477 type = vhandler.getClassFromType(id);
aoqi@0 2478 }
aoqi@0 2479 catch(ClassNotFoundException cnfe){
aoqi@0 2480 // Make sure type = null
aoqi@0 2481 type = null;
aoqi@0 2482 }
aoqi@0 2483 String signature = null;
aoqi@0 2484 if (type != null)
aoqi@0 2485 signature = ValueUtility.getSignature(fields[i]);
aoqi@0 2486
aoqi@0 2487 // Read value
aoqi@0 2488 try {
aoqi@0 2489 if ((signature != null) && ( signature.equals("Ljava/lang/Object;") ||
aoqi@0 2490 signature.equals("Ljava/io/Serializable;") ||
aoqi@0 2491 signature.equals("Ljava/io/Externalizable;")) ) {
aoqi@0 2492 javax.rmi.CORBA.Util.readAny(orbStream);
aoqi@0 2493 }
aoqi@0 2494 else {
aoqi@0 2495 // Decide what method call to make based on the type.
aoqi@0 2496 //
aoqi@0 2497 // NOTE : Since FullValueDescription does not allow us
aoqi@0 2498 // to ask whether something is an interface we do not
aoqi@0 2499 // have the ability to optimize this check.
aoqi@0 2500
aoqi@0 2501 int callType = ValueHandlerImpl.kValueType;
aoqi@0 2502
aoqi@0 2503 if (!vhandler.isSequence(id)) {
aoqi@0 2504 FullValueDescription fieldFVD = sender.meta(fields[i].id);
aoqi@0 2505 if (kRemoteTypeCode == fields[i].type) {
aoqi@0 2506
aoqi@0 2507 // RMI Object reference...
aoqi@0 2508 callType = ValueHandlerImpl.kRemoteType;
aoqi@0 2509 } else if (fieldFVD.is_abstract) {
aoqi@0 2510 // RMI Abstract Object reference...
aoqi@0 2511
aoqi@0 2512 callType = ValueHandlerImpl.kAbstractType;
aoqi@0 2513 }
aoqi@0 2514 }
aoqi@0 2515
aoqi@0 2516 // Now that we have used the FVD of the field to determine the proper course
aoqi@0 2517 // of action, it is ok to use the type (Class) from this point forward since
aoqi@0 2518 // the rep. id for this read will also follow on the wire.
aoqi@0 2519
aoqi@0 2520 switch (callType) {
aoqi@0 2521 case ValueHandlerImpl.kRemoteType:
aoqi@0 2522 orbStream.read_Object();
aoqi@0 2523 break;
aoqi@0 2524 case ValueHandlerImpl.kAbstractType:
aoqi@0 2525 orbStream.read_abstract_interface();
aoqi@0 2526 break;
aoqi@0 2527 case ValueHandlerImpl.kValueType:
aoqi@0 2528 if (type != null) {
aoqi@0 2529 orbStream.read_value(type);
aoqi@0 2530 } else {
aoqi@0 2531 orbStream.read_value();
aoqi@0 2532 }
aoqi@0 2533 break;
aoqi@0 2534 default:
aoqi@0 2535 // XXX I18N, logging needed.
aoqi@0 2536 throw new StreamCorruptedException("Unknown callType: "
aoqi@0 2537 + callType);
aoqi@0 2538 }
aoqi@0 2539 }
aoqi@0 2540
aoqi@0 2541 }
aoqi@0 2542 catch(IndirectionException cdrie) {
aoqi@0 2543 // Since we are throwing this away, don't bother handling recursion.
aoqi@0 2544 continue;
aoqi@0 2545 }
aoqi@0 2546
aoqi@0 2547 break;
aoqi@0 2548 default:
aoqi@0 2549 // XXX I18N, logging needed.
aoqi@0 2550 throw new StreamCorruptedException("Unknown kind: "
aoqi@0 2551 + fields[i].type.kind().value());
aoqi@0 2552
aoqi@0 2553 }
aoqi@0 2554 } catch (IllegalArgumentException e) {
aoqi@0 2555 /* This case should never happen. If the field types
aoqi@0 2556 are not the same, InvalidClassException is raised when
aoqi@0 2557 matching the local class to the serialized ObjectStreamClass. */
aoqi@0 2558 // XXX I18N, logging needed.
aoqi@0 2559 ClassCastException cce = new ClassCastException("Assigning instance of class " +
aoqi@0 2560 fields[i].id + " to field " + currentClassDesc.getName() +
aoqi@0 2561 '#' + fields[i].name);
aoqi@0 2562 cce.initCause(e) ;
aoqi@0 2563 throw cce ;
aoqi@0 2564 }
aoqi@0 2565 }
aoqi@0 2566
aoqi@0 2567 }
aoqi@0 2568
msheppar@984 2569 private static void setObjectField(Object o, Class c, String fieldName, Object v) {
aoqi@0 2570 try {
aoqi@0 2571 Field fld = c.getDeclaredField( fieldName ) ;
aoqi@0 2572 Class fieldCl = fld.getType();
aoqi@0 2573 if(v != null && !fieldCl.isInstance(v)) {
aoqi@0 2574 throw new Exception();
aoqi@0 2575 }
aoqi@0 2576 long key = bridge.objectFieldOffset( fld ) ;
aoqi@0 2577 bridge.putObject( o, key, v ) ;
aoqi@0 2578 } catch (Exception e) {
msheppar@984 2579 if (o != null) {
msheppar@984 2580 throw utilWrapper.errorSetObjectField( e, fieldName,
msheppar@984 2581 o.toString(),
msheppar@984 2582 v.toString() ) ;
msheppar@984 2583 } else {
msheppar@984 2584 throw utilWrapper.errorSetObjectField( e, fieldName,
msheppar@984 2585 "null " + c.getName() + " object",
msheppar@984 2586 v.toString() ) ;
msheppar@984 2587 }
aoqi@0 2588 }
aoqi@0 2589 }
aoqi@0 2590
aoqi@0 2591 private static void setBooleanField(Object o, Class c, String fieldName, boolean v)
aoqi@0 2592 {
aoqi@0 2593 try {
aoqi@0 2594 Field fld = c.getDeclaredField( fieldName ) ;
msheppar@984 2595 if ((fld != null) && (fld.getType() == Boolean.TYPE)) {
msheppar@984 2596 long key = bridge.objectFieldOffset( fld ) ;
msheppar@984 2597 bridge.putBoolean( o, key, v ) ;
msheppar@984 2598 } else {
msheppar@984 2599 throw new InvalidObjectException("Field Type mismatch");
msheppar@984 2600 }
aoqi@0 2601 } catch (Exception e) {
msheppar@984 2602 if (o != null) {
aoqi@0 2603 throw utilWrapper.errorSetBooleanField( e, fieldName,
aoqi@0 2604 o.toString(),
aoqi@0 2605 new Boolean(v) ) ;
msheppar@984 2606 } else {
msheppar@984 2607 throw utilWrapper.errorSetBooleanField( e, fieldName,
msheppar@984 2608 "null " + c.getName() + " object",
msheppar@984 2609 new Boolean(v) ) ;
msheppar@984 2610 }
aoqi@0 2611 }
aoqi@0 2612 }
aoqi@0 2613
aoqi@0 2614 private static void setByteField(Object o, Class c, String fieldName, byte v)
aoqi@0 2615 {
aoqi@0 2616 try {
aoqi@0 2617 Field fld = c.getDeclaredField( fieldName ) ;
msheppar@984 2618 if ((fld != null) && (fld.getType() == Byte.TYPE)) {
msheppar@984 2619 long key = bridge.objectFieldOffset( fld ) ;
msheppar@984 2620 bridge.putByte( o, key, v ) ;
msheppar@984 2621 } else {
msheppar@984 2622 throw new InvalidObjectException("Field Type mismatch");
msheppar@984 2623 }
aoqi@0 2624 } catch (Exception e) {
msheppar@984 2625 if (o != null) {
msheppar@984 2626 throw utilWrapper.errorSetByteField( e, fieldName,
msheppar@984 2627 o.toString(),
msheppar@984 2628 new Byte(v) ) ;
msheppar@984 2629 } else {
msheppar@984 2630 throw utilWrapper.errorSetByteField( e, fieldName,
msheppar@984 2631 "null " + c.getName() + " object",
msheppar@984 2632 new Byte(v) ) ;
msheppar@984 2633 }
aoqi@0 2634 }
aoqi@0 2635 }
aoqi@0 2636
aoqi@0 2637 private static void setCharField(Object o, Class c, String fieldName, char v)
aoqi@0 2638 {
aoqi@0 2639 try {
aoqi@0 2640 Field fld = c.getDeclaredField( fieldName ) ;
msheppar@984 2641 if ((fld != null) && (fld.getType() == Character.TYPE)) {
msheppar@984 2642 long key = bridge.objectFieldOffset( fld ) ;
msheppar@984 2643 bridge.putChar( o, key, v ) ;
msheppar@984 2644 } else {
msheppar@984 2645 throw new InvalidObjectException("Field Type mismatch");
msheppar@984 2646 }
aoqi@0 2647 } catch (Exception e) {
msheppar@984 2648 if (o != null) {
msheppar@984 2649 throw utilWrapper.errorSetCharField( e, fieldName,
msheppar@984 2650 o.toString(),
msheppar@984 2651 new Character(v) ) ;
msheppar@984 2652 } else {
msheppar@984 2653 throw utilWrapper.errorSetCharField( e, fieldName,
msheppar@984 2654 "null " + c.getName() + " object",
msheppar@984 2655 new Character(v) ) ;
msheppar@984 2656 }
aoqi@0 2657 }
aoqi@0 2658 }
aoqi@0 2659
aoqi@0 2660 private static void setShortField(Object o, Class c, String fieldName, short v)
aoqi@0 2661 {
aoqi@0 2662 try {
aoqi@0 2663 Field fld = c.getDeclaredField( fieldName ) ;
msheppar@984 2664 if ((fld != null) && (fld.getType() == Short.TYPE)) {
msheppar@984 2665 long key = bridge.objectFieldOffset( fld ) ;
msheppar@984 2666 bridge.putShort( o, key, v ) ;
msheppar@984 2667 } else {
msheppar@984 2668 throw new InvalidObjectException("Field Type mismatch");
msheppar@984 2669 }
aoqi@0 2670 } catch (Exception e) {
msheppar@984 2671 if (o != null) {
aoqi@0 2672 throw utilWrapper.errorSetShortField( e, fieldName,
aoqi@0 2673 o.toString(),
aoqi@0 2674 new Short(v) ) ;
msheppar@984 2675 } else {
msheppar@984 2676 throw utilWrapper.errorSetShortField( e, fieldName,
msheppar@984 2677 "null " + c.getName() + " object",
msheppar@984 2678 new Short(v) ) ;
msheppar@984 2679 }
aoqi@0 2680 }
aoqi@0 2681 }
aoqi@0 2682
aoqi@0 2683 private static void setIntField(Object o, Class c, String fieldName, int v)
aoqi@0 2684 {
aoqi@0 2685 try {
aoqi@0 2686 Field fld = c.getDeclaredField( fieldName ) ;
msheppar@984 2687 if ((fld != null) && (fld.getType() == Integer.TYPE)) {
msheppar@984 2688 long key = bridge.objectFieldOffset( fld ) ;
msheppar@984 2689 bridge.putInt( o, key, v ) ;
msheppar@984 2690 } else {
msheppar@984 2691 throw new InvalidObjectException("Field Type mismatch");
msheppar@984 2692 }
aoqi@0 2693 } catch (Exception e) {
msheppar@984 2694 if (o != null) {
msheppar@984 2695 throw utilWrapper.errorSetIntField( e, fieldName,
msheppar@984 2696 o.toString(),
msheppar@984 2697 new Integer(v) ) ;
msheppar@984 2698 } else {
msheppar@984 2699 throw utilWrapper.errorSetIntField( e, fieldName,
msheppar@984 2700 "null " + c.getName() + " object",
msheppar@984 2701 new Integer(v) ) ;
msheppar@984 2702 }
aoqi@0 2703 }
aoqi@0 2704 }
aoqi@0 2705
aoqi@0 2706 private static void setLongField(Object o, Class c, String fieldName, long v)
aoqi@0 2707 {
aoqi@0 2708 try {
aoqi@0 2709 Field fld = c.getDeclaredField( fieldName ) ;
msheppar@984 2710 if ((fld != null) && (fld.getType() == Long.TYPE)) {
msheppar@984 2711 long key = bridge.objectFieldOffset( fld ) ;
msheppar@984 2712 bridge.putLong( o, key, v ) ;
msheppar@984 2713 } else {
msheppar@984 2714 throw new InvalidObjectException("Field Type mismatch");
msheppar@984 2715 }
aoqi@0 2716 } catch (Exception e) {
msheppar@984 2717 if (o != null) {
msheppar@984 2718 throw utilWrapper.errorSetLongField( e, fieldName,
msheppar@984 2719 o.toString(),
msheppar@984 2720 new Long(v) ) ;
msheppar@984 2721 } else {
msheppar@984 2722 throw utilWrapper.errorSetLongField( e, fieldName,
msheppar@984 2723 "null " + c.getName() + " object",
msheppar@984 2724 new Long(v) ) ;
msheppar@984 2725 }
aoqi@0 2726 }
aoqi@0 2727 }
aoqi@0 2728
aoqi@0 2729 private static void setFloatField(Object o, Class c, String fieldName, float v)
aoqi@0 2730 {
aoqi@0 2731 try {
aoqi@0 2732 Field fld = c.getDeclaredField( fieldName ) ;
msheppar@984 2733 if ((fld != null) && (fld.getType() == Float.TYPE)) {
msheppar@984 2734 long key = bridge.objectFieldOffset( fld ) ;
msheppar@984 2735 bridge.putFloat( o, key, v ) ;
msheppar@984 2736 } else {
msheppar@984 2737 throw new InvalidObjectException("Field Type mismatch");
msheppar@984 2738 }
aoqi@0 2739 } catch (Exception e) {
msheppar@984 2740 if (o != null) {
msheppar@984 2741 throw utilWrapper.errorSetFloatField( e, fieldName,
msheppar@984 2742 o.toString(),
msheppar@984 2743 new Float(v) ) ;
msheppar@984 2744 } else {
msheppar@984 2745 throw utilWrapper.errorSetFloatField( e, fieldName,
msheppar@984 2746 "null " + c.getName() + " object",
msheppar@984 2747 new Float(v) ) ;
msheppar@984 2748 }
aoqi@0 2749 }
aoqi@0 2750 }
aoqi@0 2751
aoqi@0 2752 private static void setDoubleField(Object o, Class c, String fieldName, double v)
aoqi@0 2753 {
aoqi@0 2754 try {
aoqi@0 2755 Field fld = c.getDeclaredField( fieldName ) ;
msheppar@984 2756 if ((fld != null) && (fld.getType() == Double.TYPE)) {
msheppar@984 2757 long key = bridge.objectFieldOffset( fld ) ;
msheppar@984 2758 bridge.putDouble( o, key, v ) ;
msheppar@984 2759 } else {
msheppar@984 2760 throw new InvalidObjectException("Field Type mismatch");
msheppar@984 2761 }
aoqi@0 2762 } catch (Exception e) {
msheppar@984 2763 if (o != null) {
msheppar@984 2764 throw utilWrapper.errorSetDoubleField( e, fieldName,
msheppar@984 2765 o.toString(),
msheppar@984 2766 new Double(v) ) ;
msheppar@984 2767 } else {
msheppar@984 2768 throw utilWrapper.errorSetDoubleField( e, fieldName,
msheppar@984 2769 "null " + c.getName() + " object",
msheppar@984 2770 new Double(v) ) ;
msheppar@984 2771 }
aoqi@0 2772 }
aoqi@0 2773 }
aoqi@0 2774
aoqi@0 2775 /**
aoqi@0 2776 * This class maintains a map of stream position to
aoqi@0 2777 * an Object currently being deserialized. It is used
aoqi@0 2778 * to handle the cases where the are indirections to
aoqi@0 2779 * an object on the recursion stack. The CDR level
aoqi@0 2780 * handles indirections to objects previously seen
aoqi@0 2781 * (and completely deserialized) in the stream.
aoqi@0 2782 */
aoqi@0 2783 static class ActiveRecursionManager
aoqi@0 2784 {
aoqi@0 2785 private Map offsetToObjectMap;
aoqi@0 2786
aoqi@0 2787 public ActiveRecursionManager() {
aoqi@0 2788 // A hash map is unsynchronized and allows
aoqi@0 2789 // null values
aoqi@0 2790 offsetToObjectMap = new HashMap();
aoqi@0 2791 }
aoqi@0 2792
aoqi@0 2793 // Called right after allocating a new object.
aoqi@0 2794 // Offset is the starting position in the stream
aoqi@0 2795 // of the object.
aoqi@0 2796 public void addObject(int offset, Object value) {
aoqi@0 2797 offsetToObjectMap.put(new Integer(offset), value);
aoqi@0 2798 }
aoqi@0 2799
aoqi@0 2800 // If the given starting position doesn't refer
aoqi@0 2801 // to the beginning of an object currently being
aoqi@0 2802 // deserialized, this throws an IOException.
aoqi@0 2803 // Otherwise, it returns a reference to the
aoqi@0 2804 // object.
aoqi@0 2805 public Object getObject(int offset) throws IOException {
aoqi@0 2806 Integer position = new Integer(offset);
aoqi@0 2807
aoqi@0 2808 if (!offsetToObjectMap.containsKey(position))
aoqi@0 2809 // XXX I18N, logging needed.
aoqi@0 2810 throw new IOException("Invalid indirection to offset "
aoqi@0 2811 + offset);
aoqi@0 2812
aoqi@0 2813 return offsetToObjectMap.get(position);
aoqi@0 2814 }
aoqi@0 2815
aoqi@0 2816 // Called when an object has been completely
aoqi@0 2817 // deserialized, so it should no longer be in
aoqi@0 2818 // this mapping. The CDR level can handle
aoqi@0 2819 // further indirections.
aoqi@0 2820 public void removeObject(int offset) {
aoqi@0 2821 offsetToObjectMap.remove(new Integer(offset));
aoqi@0 2822 }
aoqi@0 2823
aoqi@0 2824 // If the given offset doesn't map to an Object,
aoqi@0 2825 // then it isn't an indirection to an object
aoqi@0 2826 // currently being deserialized.
aoqi@0 2827 public boolean containsObject(int offset) {
aoqi@0 2828 return offsetToObjectMap.containsKey(new Integer(offset));
aoqi@0 2829 }
aoqi@0 2830 }
aoqi@0 2831 }

mercurial