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