1. /*
  2. * @(#)CDRInputStream_1_0.java 1.83 04/01/13
  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.internal.iiop;
  16. import java.io.IOException;
  17. import java.io.Serializable;
  18. import java.io.ByteArrayInputStream;
  19. import java.io.ObjectInputStream;
  20. import java.io.IOException;
  21. import java.io.StreamCorruptedException;
  22. import java.io.OptionalDataException;
  23. import java.io.IOException;
  24. import java.util.Stack;
  25. import java.net.URL;
  26. import java.net.MalformedURLException;
  27. import java.lang.reflect.InvocationTargetException;
  28. import java.lang.reflect.Method;
  29. import java.math.BigDecimal;
  30. import java.rmi.Remote;
  31. import java.rmi.StubNotFoundException;
  32. import org.omg.CORBA.SystemException;
  33. import org.omg.CORBA.INTERNAL;
  34. import org.omg.CORBA.MARSHAL;
  35. import org.omg.CORBA.DATA_CONVERSION;
  36. import org.omg.CORBA.BAD_PARAM;
  37. import org.omg.CORBA.Object;
  38. import org.omg.CORBA.Principal;
  39. import org.omg.CORBA.TypeCode;
  40. import org.omg.CORBA.Any;
  41. import org.omg.CORBA.portable.Delegate;
  42. import org.omg.CORBA.portable.ValueBase;
  43. import org.omg.CORBA.portable.IndirectionException;
  44. import org.omg.CORBA.NO_IMPLEMENT;
  45. import org.omg.CORBA.CompletionStatus;
  46. import org.omg.CORBA.TCKind;
  47. import org.omg.CORBA.TypeCodePackage.BadKind;
  48. import org.omg.CORBA.CustomMarshal;
  49. import org.omg.CORBA.TypeCode;
  50. import org.omg.CORBA.Principal;
  51. import org.omg.CORBA.Any;
  52. import org.omg.CORBA.portable.BoxedValueHelper;
  53. import org.omg.CORBA.portable.ValueFactory;
  54. import org.omg.CORBA.portable.CustomValue;
  55. import org.omg.CORBA.portable.StreamableValue;
  56. import org.omg.CORBA.portable.ObjectImpl;
  57. import org.omg.CORBA.MARSHAL;
  58. import javax.rmi.PortableRemoteObject;
  59. import javax.rmi.CORBA.Tie;
  60. import javax.rmi.CORBA.Util;
  61. import javax.rmi.CORBA.ValueHandler;
  62. import com.sun.corba.se.internal.corba.ServerDelegate;
  63. import com.sun.corba.se.internal.corba.PrincipalImpl;
  64. import com.sun.corba.se.internal.corba.TypeCodeImpl;
  65. import com.sun.corba.se.internal.core.IOR;
  66. import com.sun.corba.se.internal.core.SubcontractRegistry;
  67. import com.sun.corba.se.internal.core.ServerSubcontract;
  68. import com.sun.corba.se.internal.core.ClientSubcontract;
  69. import com.sun.corba.se.internal.core.GIOPVersion;
  70. import com.sun.corba.se.internal.core.ORBVersionImpl;
  71. import com.sun.corba.se.internal.core.ORBVersion;
  72. import com.sun.corba.se.internal.core.CodeSetConversion;
  73. import com.sun.corba.se.internal.util.Utility;
  74. import com.sun.corba.se.internal.orbutil.RepositoryIdStrings;
  75. import com.sun.corba.se.internal.orbutil.RepositoryIdInterface;
  76. import com.sun.corba.se.internal.orbutil.RepositoryIdUtility;
  77. import com.sun.corba.se.internal.orbutil.RepositoryIdFactory;
  78. import com.sun.corba.se.internal.orbutil.ORBUtility;
  79. import com.sun.corba.se.internal.orbutil.CacheTable;
  80. import com.sun.corba.se.internal.orbutil.MinorCodes;
  81. import com.sun.corba.se.internal.ior.ObjectKeyTemplate ;
  82. import com.sun.org.omg.CORBA.portable.ValueHelper;
  83. import com.sun.org.omg.SendingContext.CodeBase;
  84. import java.security.AccessController;
  85. import java.security.PrivilegedExceptionAction;
  86. import java.security.PrivilegedActionException;
  87. public class CDRInputStream_1_0 extends CDRInputStreamBase
  88. implements RestorableInputStream
  89. {
  90. private static final String kReadMethod = "read";
  91. private static final int maxBlockLength = 0x7fffff00;
  92. protected BufferManagerRead bufferManagerRead;
  93. protected ByteBufferWithInfo bbwi;
  94. // Set to the ORB's transportDebugFlag value. This value is
  95. // used if the ORB is null.
  96. private boolean debug = false;
  97. protected boolean littleEndian;
  98. protected com.sun.corba.se.internal.corba.ORB orb;
  99. protected ValueHandler valueHandler = null;
  100. // Value cache
  101. private CacheTable valueCache = null;
  102. // Repository ID cache
  103. private CacheTable repositoryIdCache = null;
  104. // codebase cache
  105. private CacheTable codebaseCache = null;
  106. // Current Class Stack (repository Ids of current class being read)
  107. // private Stack currentStack = null;
  108. // Length of current chunk, or a large positive number if not in a chunk
  109. protected int blockLength = maxBlockLength;
  110. // Read end flag (value nesting depth)
  111. protected int end_flag = 0;
  112. // Beginning with the resolution to interop issue 4328,
  113. // only enclosing chunked valuetypes are taken into account
  114. // when computing the nesting level. However, we still need
  115. // the old computation around for interoperability with our
  116. // older ORBs.
  117. private int chunkedValueNestingLevel = 0;
  118. // Flag used to determine whether blocksize was zero
  119. // private int checkForNullBlock = -1;
  120. // In block flag
  121. // private boolean inBlock = false;
  122. // Indicates whether we are inside a value
  123. // private boolean outerValueDone = true;
  124. // Int used by read_value(Serializable) that is set by this class
  125. // before calling ValueFactory.read_value
  126. protected int valueIndirection = 0;
  127. // Int set by readStringOrIndirection to communicate the actual
  128. // offset of the string length field back to the caller
  129. protected int stringIndirection = 0;
  130. // Flag indicating whether we are unmarshalling a chunked value
  131. protected boolean isChunked = false;
  132. // Repository ID handlers
  133. private RepositoryIdUtility repIdUtil;
  134. private RepositoryIdStrings repIdStrs;
  135. // Code set converters (created when first needed)
  136. private CodeSetConversion.BTCConverter charConverter;
  137. private CodeSetConversion.BTCConverter wcharConverter;
  138. // Template method
  139. public CDRInputStreamBase dup() {
  140. CDRInputStreamBase result;
  141. try {
  142. result = (CDRInputStreamBase)this.getClass().newInstance();
  143. } catch (InstantiationException e) {
  144. debugPrintThrowable(e);
  145. throw new INTERNAL();
  146. } catch (IllegalAccessException e) {
  147. debugPrintThrowable(e);
  148. throw new INTERNAL();
  149. }
  150. result.init(this.orb,
  151. this.bbwi.buf,
  152. this.bbwi.buflen,
  153. this.littleEndian,
  154. this.bufferManagerRead);
  155. ((CDRInputStream_1_0)result).bbwi.index = this.bbwi.index;
  156. return result;
  157. }
  158. /**
  159. * NOTE: size passed to init means buffer size
  160. */
  161. public void init(org.omg.CORBA.ORB orb,
  162. byte[] data,
  163. int size,
  164. boolean littleEndian,
  165. BufferManagerRead bufferManager)
  166. {
  167. this.orb = (com.sun.corba.se.internal.corba.ORB)orb;
  168. this.littleEndian = littleEndian;
  169. this.bufferManagerRead = bufferManager;
  170. this.bbwi = new ByteBufferWithInfo(data, 0);
  171. this.bbwi.buflen = size;
  172. this.markAndResetHandler = bufferManagerRead.getMarkAndResetHandler();
  173. // The ORB seems to be null in some cases due to primitive
  174. // TypeCodeImpls (which are singletons) not having ORB instances.
  175. if (orb != null)
  176. debug = ((com.sun.corba.se.internal.corba.ORB)orb).transportDebugFlag;
  177. }
  178. // See description in CDRInputStream
  179. void performORBVersionSpecificInit() {
  180. createRepositoryIdHandlers();
  181. }
  182. private final void createRepositoryIdHandlers()
  183. {
  184. if (orb != null) {
  185. // Get the appropriate versions based on the ORB version. The
  186. // ORB versioning info is only in the corba ORB.
  187. repIdUtil = RepositoryIdFactory.getRepIdUtility(orb);
  188. repIdStrs = RepositoryIdFactory.getRepIdStringsFactory(orb);
  189. } else {
  190. // Get the latest versions
  191. repIdUtil = RepositoryIdFactory.getRepIdUtility();
  192. repIdStrs = RepositoryIdFactory.getRepIdStringsFactory();
  193. }
  194. }
  195. public GIOPVersion getGIOPVersion() {
  196. return GIOPVersion.V1_0;
  197. }
  198. protected final int computeAlignment(int align) {
  199. if (align > 1) {
  200. int incr = bbwi.index & (align - 1);
  201. if (incr != 0)
  202. return align - incr;
  203. }
  204. return 0;
  205. }
  206. public int getSize()
  207. {
  208. return bbwi.index;
  209. }
  210. protected void checkBlockLength() {
  211. // Since chunks can end at arbitrary points (though not within
  212. // primitive CDR types, arrays of primitives, strings, or wstrings),
  213. // we must check here for termination of the current chunk.
  214. // This also takes care of terminating an open chunk when a
  215. // value tag is encountered.
  216. if (!isChunked)
  217. return;
  218. if (blockLength == get_offset()) {
  219. blockLength = maxBlockLength;
  220. start_block();
  221. } else if (blockLength < get_offset()) {
  222. // current chunk has overflowed
  223. throw new MARSHAL("Chunk overflow at offset " + get_offset(),
  224. com.sun.corba.se.internal.orbutil.MinorCodes.CHUNK_OVERFLOW,
  225. CompletionStatus.COMPLETED_NO);
  226. }
  227. }
  228. protected void alignAndCheck(int align, int n) {
  229. checkBlockLength();
  230. bbwi.index += computeAlignment(align);
  231. if (bbwi.index + n > bbwi.buflen)
  232. grow(align, n);
  233. }
  234. //
  235. // This can be overridden....
  236. //
  237. protected void grow(int align, int n) {
  238. bbwi.needed = n;
  239. bbwi = bufferManagerRead.underflow(bbwi);
  240. }
  241. //
  242. // Marshal primitives.
  243. //
  244. public final void consumeEndian() {
  245. littleEndian = read_boolean();
  246. }
  247. // No such type in java
  248. public final double read_longdouble() {
  249. throw new NO_IMPLEMENT(com.sun.corba.se.internal.orbutil.MinorCodes.SEND_DEFERRED_NOTIMPLEMENTED,
  250. CompletionStatus.COMPLETED_MAYBE);
  251. }
  252. public final boolean read_boolean() {
  253. return (read_octet() != 0);
  254. }
  255. public final char read_char() {
  256. alignAndCheck(1, 1);
  257. return getConvertedChars(1, getCharConverter())[0];
  258. }
  259. public char read_wchar() {
  260. // Don't allow transmission of wchar/wstring data with
  261. // foreign ORBs since it's against the spec.
  262. if (ORBUtility.isForeignORB((com.sun.corba.se.internal.corba.ORB)orb)) {
  263. throw new MARSHAL(MinorCodes.WCHAR_DATA_IN_GIOP_1_0,
  264. CompletionStatus.COMPLETED_MAYBE);
  265. }
  266. // If we're talking to one of our legacy ORBs, do what
  267. // they did:
  268. int b1, b2;
  269. alignAndCheck(2, 2);
  270. if (littleEndian) {
  271. b2 = bbwi.buf[bbwi.index++] & 0x00FF;
  272. b1 = bbwi.buf[bbwi.index++] & 0x00FF;
  273. } else {
  274. b1 = bbwi.buf[bbwi.index++] & 0x00FF;
  275. b2 = bbwi.buf[bbwi.index++] & 0x00FF;
  276. }
  277. return (char)((b1 << 8) + (b2 << 0));
  278. }
  279. public final byte read_octet() {
  280. alignAndCheck(1, 1);
  281. return bbwi.buf[bbwi.index++];
  282. }
  283. public final short read_short() {
  284. int b1, b2;
  285. alignAndCheck(2, 2);
  286. if (littleEndian) {
  287. b2 = (bbwi.buf[bbwi.index++] << 0) & 0x000000FF;
  288. b1 = (bbwi.buf[bbwi.index++] << 8) & 0x0000FF00;
  289. } else {
  290. b1 = (bbwi.buf[bbwi.index++] << 8) & 0x0000FF00;
  291. b2 = (bbwi.buf[bbwi.index++] << 0) & 0x000000FF;
  292. }
  293. return (short)(b1 | b2);
  294. }
  295. public final short read_ushort() {
  296. return read_short();
  297. }
  298. public final int read_long() {
  299. int b1, b2, b3, b4;
  300. alignAndCheck(4, 4);
  301. if (littleEndian) {
  302. b4 = bbwi.buf[bbwi.index++] & 0xFF;
  303. b3 = bbwi.buf[bbwi.index++] & 0xFF;
  304. b2 = bbwi.buf[bbwi.index++] & 0xFF;
  305. b1 = bbwi.buf[bbwi.index++] & 0xFF;
  306. } else {
  307. b1 = bbwi.buf[bbwi.index++] & 0xFF;
  308. b2 = bbwi.buf[bbwi.index++] & 0xFF;
  309. b3 = bbwi.buf[bbwi.index++] & 0xFF;
  310. b4 = bbwi.buf[bbwi.index++] & 0xFF;
  311. }
  312. return (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
  313. }
  314. public final int read_ulong() {
  315. return read_long();
  316. }
  317. public final long read_longlong() {
  318. long i1, i2;
  319. alignAndCheck(8, 8);
  320. if (littleEndian) {
  321. i2 = read_long() & 0xFFFFFFFFL;
  322. i1 = (long)read_long() << 32;
  323. } else {
  324. i1 = (long)read_long() << 32;
  325. i2 = read_long() & 0xFFFFFFFFL;
  326. }
  327. return (i1 | i2);
  328. }
  329. public final long read_ulonglong() {
  330. return read_longlong();
  331. }
  332. public final float read_float() {
  333. return Float.intBitsToFloat(read_long());
  334. }
  335. public final double read_double() {
  336. return Double.longBitsToDouble(read_longlong());
  337. }
  338. protected final void checkForNegativeLength(int length) {
  339. if (length < 0)
  340. throw new MARSHAL("Bad string length: " + length,
  341. MinorCodes.NEGATIVE_STRING_LENGTH,
  342. CompletionStatus.COMPLETED_MAYBE);
  343. }
  344. protected final String readStringOrIndirection(boolean allowIndirection) {
  345. int len = read_long();
  346. //
  347. // Check for indirection
  348. //
  349. if (allowIndirection) {
  350. if (len == 0xffffffff)
  351. return null;
  352. else
  353. stringIndirection = get_offset() - 4;
  354. }
  355. checkForNegativeLength(len);
  356. if (orb != null && ORBUtility.isLegacyORB((com.sun.corba.se.internal.corba.ORB)orb))
  357. return legacyReadString(len);
  358. else
  359. return internalReadString(len);
  360. }
  361. private final String internalReadString(int len) {
  362. // Workaround for ORBs which send string lengths of
  363. // zero to mean empty string.
  364. // IMPORTANT: Do not replace 'new String("")' with "", it may result
  365. // in a Serialization bug (See serialization.zerolengthstring) and
  366. // bug id: 4728756 for details
  367. if (len == 0)
  368. return new String("");
  369. char[] result = getConvertedChars(len - 1, getCharConverter());
  370. // Skip over the 1 byte null
  371. read_octet();
  372. return new String(result, 0, getCharConverter().getNumChars());
  373. }
  374. private final String legacyReadString(int len) {
  375. //
  376. // Workaround for ORBs which send string lengths of
  377. // zero to mean empty string.
  378. //
  379. // IMPORTANT: Do not replace 'new String("")' with "", it may result
  380. // in a Serialization bug (See serialization.zerolengthstring) and
  381. // bug id: 4728756 for details
  382. if (len == 0)
  383. return new String("");
  384. len--;
  385. char[] c = new char[len];
  386. int n = 0;
  387. while (n < len) {
  388. int avail;
  389. int bytes;
  390. int wanted;
  391. avail = bbwi.buflen - bbwi.index;
  392. if (avail <= 0) {
  393. grow(1, 1);
  394. avail = bbwi.buflen - bbwi.index;
  395. }
  396. wanted = len - n;
  397. bytes = (wanted < avail) ? wanted : avail;
  398. for (int i=0; i<bytes; i++) {
  399. c[n+i] = (char) (bbwi.buf[bbwi.index+i] & 0xFF);
  400. }
  401. bbwi.index += bytes;
  402. n += bytes;
  403. }
  404. //
  405. // Skip past terminating null byte
  406. //
  407. if (bbwi.index + 1 > bbwi.buflen)
  408. alignAndCheck(1, 1);
  409. bbwi.index++;
  410. return new String(c);
  411. }
  412. public final String read_string() {
  413. return readStringOrIndirection(false);
  414. }
  415. public String read_wstring() {
  416. // Don't allow transmission of wchar/wstring data with
  417. // foreign ORBs since it's against the spec.
  418. if (ORBUtility.isForeignORB((com.sun.corba.se.internal.corba.ORB)orb)) {
  419. throw new MARSHAL(MinorCodes.WCHAR_DATA_IN_GIOP_1_0,
  420. CompletionStatus.COMPLETED_MAYBE);
  421. }
  422. int len = read_long();
  423. //
  424. // Workaround for ORBs which send string lengths of
  425. // zero to mean empty string.
  426. //
  427. // IMPORTANT: Do not replace 'new String("")' with "", it may result
  428. // in a Serialization bug (See serialization.zerolengthstring) and
  429. // bug id: 4728756 for details
  430. if (len == 0)
  431. return new String("");
  432. checkForNegativeLength(len);
  433. len--;
  434. char[] c = new char[len];
  435. for (int i = 0; i < len; i++)
  436. c[i] = read_wchar();
  437. // skip the two null terminator bytes
  438. read_wchar();
  439. // bbwi.index += 2;
  440. return new String(c);
  441. }
  442. public final void read_octet_array(byte[] b, int offset, int length) {
  443. if ( b == null )
  444. throw new BAD_PARAM();
  445. // Must call alignAndCheck at least once to ensure
  446. // we aren't at the end of a chunk. Of course, we
  447. // should only call it if we actually need to read
  448. // something, otherwise we might end up with an
  449. // exception at the end of the stream.
  450. if (length == 0)
  451. return;
  452. alignAndCheck(1, 1);
  453. int n = offset;
  454. while (n < length+offset) {
  455. int avail;
  456. int bytes;
  457. int wanted;
  458. avail = bbwi.buflen - bbwi.index;
  459. if (avail <= 0) {
  460. grow(1, 1);
  461. avail = bbwi.buflen - bbwi.index;
  462. }
  463. wanted = (length + offset) - n;
  464. bytes = (wanted < avail) ? wanted : avail;
  465. System.arraycopy(bbwi.buf, bbwi.index, b, n, bytes);
  466. bbwi.index += bytes;
  467. n += bytes;
  468. }
  469. }
  470. public Principal read_Principal() {
  471. int len = read_long();
  472. byte[] pvalue = new byte[len];
  473. read_octet_array(pvalue,0,len);
  474. Principal p = new PrincipalImpl();
  475. p.name(pvalue);
  476. return p;
  477. }
  478. public TypeCode read_TypeCode() {
  479. TypeCodeImpl tc = new TypeCodeImpl(orb);
  480. tc.read_value(parent);
  481. return tc;
  482. }
  483. public Any read_any() {
  484. Any any = orb.create_any();
  485. TypeCodeImpl tc = new TypeCodeImpl(orb);
  486. // read off the typecode
  487. // REVISIT We could avoid this try-catch if we could peek the typecode kind
  488. // off this stream and see if it is a tk_value.
  489. // Looking at the code we know that for tk_value the Any.read_value() below
  490. // ignores the tc argument anyway (except for the kind field).
  491. // But still we would need to make sure that the whole typecode, including
  492. // encapsulations, is read off.
  493. try {
  494. tc.read_value(parent);
  495. } catch (MARSHAL ex) {
  496. if (tc.kind().value() != TCKind._tk_value)
  497. throw ex;
  498. // We can be sure that the whole typecode encapsulation has been read off.
  499. //System.out.println("Error reading value tc " + tc + ", falling back on ValueHandler");
  500. debugPrintThrowable(ex);
  501. }
  502. // read off the value of the any
  503. any.read_value(parent, tc);
  504. return any;
  505. }
  506. public org.omg.CORBA.Object read_Object() {
  507. return read_Object(null);
  508. }
  509. // ------------ RMI related methods --------------------------
  510. // IDL to Java ptc-00-01-08 1.21.4.1
  511. //
  512. // The clz argument to read_Object can be either a stub
  513. // Class or the "Class object for the RMI/IDL interface type
  514. // that is statically expected."
  515. public org.omg.CORBA.Object read_Object(Class clz) {
  516. IOR ior = new IOR(parent) ;
  517. if (clz == null || ObjectImpl.class.isAssignableFrom(clz)) {
  518. // We were given null or a stub class
  519. return CDRInputStream_1_0.internalIORToObject(ior, clz, orb);
  520. } else {
  521. // We must have been given the Class object for the RMI/IDL
  522. // interface
  523. try {
  524. Class stubClass
  525. = Utility.loadStubClass(ior.getTypeId(),
  526. ior.getCodebase(),
  527. clz);
  528. return CDRInputStream_1_0.internalIORToObject(ior,
  529. stubClass,
  530. orb);
  531. } catch (ClassNotFoundException cnfe) {
  532. // Failed to load the stub class.
  533. throw new MARSHAL("Failed to load stub for "
  534. + ior.getTypeId()
  535. + " with Class "
  536. + (clz == null ? "null" : clz.getName()),
  537. MinorCodes.READ_OBJECT_EXCEPTION,
  538. CompletionStatus.COMPLETED_NO);
  539. }
  540. }
  541. }
  542. /*
  543. * This is used as a general utility (e.g., the PortableInterceptor
  544. * implementation uses it. NOTE: The Class passed in must be the
  545. * Stub Class.
  546. */
  547. public static org.omg.CORBA.Object internalIORToObject(
  548. IOR ior, Class stubClass, com.sun.corba.se.internal.core.ORB orb)
  549. {
  550. if (ior.is_nil())
  551. return null;
  552. if (ior.isLocal()) {
  553. // Ok so far. Can we get a valid servant?
  554. ServerSubcontract sc = ior.getServerSubcontract() ;
  555. if (sc != null && (sc.isServantSupported())) {
  556. java.lang.Object servant = sc.getServant(ior);
  557. if (servant != null ) {
  558. // Got a valid servant. Is it a Tie?
  559. if (servant instanceof Tie) {
  560. // Yes, so it is a local servant. Load a stub
  561. // for it using the codebase from the IOR and
  562. // the delegate from the tie.
  563. String codebase = ior.getCodebase();
  564. org.omg.CORBA.Object objref = (org.omg.CORBA.Object)
  565. Utility.loadStub((Tie)servant,stubClass,codebase,false);
  566. // If we managed to load a stub, return it, otherwise we
  567. // must fail...
  568. if (objref != null) {
  569. return objref;
  570. } else {
  571. throw new MARSHAL(
  572. com.sun.corba.se.internal.orbutil.MinorCodes.READ_OBJECT_EXCEPTION,
  573. CompletionStatus.COMPLETED_NO);
  574. }
  575. } else if (servant instanceof org.omg.CORBA.Object) {
  576. if (servant instanceof org.omg.CORBA.portable.InvokeHandler) {
  577. // Old ImplBase stubs are CORBA.Objects.
  578. // However, they are not stubs.
  579. return createDelegate(ior, stubClass, orb);
  580. } else {
  581. // No, so assume IDL style stub...
  582. return (org.omg.CORBA.Object) servant;
  583. }
  584. } else
  585. throw new INTERNAL( MinorCodes.BAD_SERVANT_READ_OBJECT,
  586. CompletionStatus.COMPLETED_NO ) ;
  587. }
  588. }
  589. }
  590. return createDelegate(ior, stubClass, orb);
  591. }
  592. protected static org.omg.CORBA.Object createDelegate(
  593. IOR ior, Class stubClass, com.sun.corba.se.internal.core.ORB orb)
  594. {
  595. SubcontractRegistry registry = orb.getSubcontractRegistry() ;
  596. ObjectKeyTemplate temp = ior.getProfile().getTemplate().getObjectKeyTemplate() ;
  597. ClientSubcontract rep = registry.getClientSubcontract(temp);
  598. rep.unmarshal(ior);
  599. rep.setOrb(orb);
  600. // Load stub, set the delegate and return it...
  601. return loadStub(ior,stubClass,(Delegate)rep);
  602. }
  603. protected static ObjectImpl loadStub(IOR ior,
  604. Class stubClass,
  605. Delegate delegate) {
  606. // Use the stubClass, if we have it...
  607. if (stubClass != null) {
  608. try {
  609. return newStub(stubClass,delegate);
  610. } catch (Throwable e) {
  611. if (e instanceof ThreadDeath) {
  612. throw (ThreadDeath) e;
  613. }
  614. }
  615. } else {
  616. // Try to load from the ior...
  617. try {
  618. String repID = ior.getTypeId();
  619. // If the repID is "", fall thru to returning the default
  620. // stub, otherwise try to load the class...
  621. if (repID.length() > 0) {
  622. String codebase = ior.getCodebase();
  623. Class clz = Utility.loadStubClass(repID, codebase, null); //d11638
  624. return newStub(clz,delegate);
  625. }
  626. } catch (Throwable e) {
  627. if (e instanceof ThreadDeath) {
  628. throw (ThreadDeath) e;
  629. }
  630. }
  631. // Return the "default" stub...
  632. ObjectImpl objref = new org.omg.CORBA_2_3.portable.ObjectImpl() {
  633. public String[] _ids() {
  634. String[] typeids = new String[1];
  635. typeids[0] = "IDL:omg.org/CORBA/Object:1.0";
  636. return typeids;
  637. }
  638. };
  639. objref._set_delegate(delegate);
  640. return objref;
  641. }
  642. // We failed...
  643. throw new MARSHAL(com.sun.corba.se.internal.orbutil.MinorCodes.READ_OBJECT_EXCEPTION,
  644. CompletionStatus.COMPLETED_NO);
  645. }
  646. protected static ObjectImpl newStub(Class stubClass,Delegate delegate)
  647. throws InstantiationException,
  648. IllegalAccessException,
  649. NoSuchMethodException,
  650. InvocationTargetException {
  651. // What kind of stub do we have?
  652. if (java.rmi.Remote.class.isAssignableFrom(stubClass)) {
  653. // RMI. Instantiate, set delegate and return...
  654. ObjectImpl objref = (ObjectImpl) stubClass.newInstance();
  655. objref._set_delegate(delegate);
  656. return objref;
  657. }
  658. // RMI Abstract OR IDL. Instantiate, set delegate and return...
  659. try {
  660. // Try creating the stub using the default constructor...
  661. ObjectImpl result = (ObjectImpl)stubClass.newInstance();
  662. result._set_delegate(delegate);
  663. return result;
  664. } catch (Throwable e) {
  665. if (e instanceof ThreadDeath) {
  666. throw (ThreadDeath) e;
  667. }
  668. }
  669. // Try creating the stub using the delegate constructor...
  670. Class[] intArgsClass = new Class[] {org.omg.CORBA.portable.Delegate.class};
  671. java.lang.Object[]intArgs = new java.lang.Object[] {delegate};
  672. java.lang.reflect.Constructor intArgsConstructor;
  673. intArgsConstructor = stubClass.getConstructor(intArgsClass);
  674. return (ObjectImpl)intArgsConstructor.newInstance(intArgs);
  675. }
  676. public java.lang.Object read_abstract_interface() {
  677. return read_abstract_interface(null);
  678. }
  679. public java.lang.Object read_abstract_interface(java.lang.Class clz) {
  680. boolean object = read_boolean();
  681. if (object) {
  682. return read_Object(clz);
  683. } else {
  684. return read_value();
  685. }
  686. }
  687. public Serializable read_value() {
  688. // Read value tag
  689. int vType = readValueTag();
  690. if (vType == 0)
  691. return null; // value is null
  692. else if (vType == 0xffffffff) { // Indirection tag
  693. int indirection = read_long() + get_offset() - 4;
  694. if (valueCache != null && valueCache.containsVal(indirection))
  695. {
  696. java.io.Serializable cachedValue = (java.io.Serializable)valueCache.getKey(indirection);
  697. return cachedValue;
  698. }
  699. else {
  700. throw new IndirectionException(indirection);
  701. }
  702. }
  703. else {
  704. int indirection = get_offset() - 4;
  705. // end_block();
  706. boolean saveIsChunked = isChunked;
  707. isChunked = repIdUtil.isChunkedEncoding(vType);
  708. java.lang.Object value = null;
  709. String codebase_URL = null;
  710. if (repIdUtil.isCodeBasePresent(vType)){
  711. codebase_URL = read_codebase_URL();
  712. }
  713. // Read repository id
  714. String repositoryIDString = null;
  715. switch(repIdUtil.getTypeInfo(vType)){
  716. case RepositoryIdUtility.NO_TYPE_INFO :
  717. throw new MARSHAL("read_value() with no repository ID info",
  718. MinorCodes.READ_VALUE_AND_NO_REP_ID,
  719. CompletionStatus.COMPLETED_MAYBE);
  720. case RepositoryIdUtility.SINGLE_REP_TYPE_INFO :
  721. repositoryIDString = read_repositoryId();
  722. break;
  723. case RepositoryIdUtility.PARTIAL_LIST_TYPE_INFO :
  724. repositoryIDString = read_repositoryIds();
  725. break;
  726. }
  727. // indirection = get_offset();
  728. start_block();
  729. end_flag--;
  730. if (isChunked)
  731. chunkedValueNestingLevel--;
  732. if (repositoryIDString.equals(repIdStrs.getWStringValueRepId()))
  733. {
  734. value = read_wstring();
  735. }
  736. else if (repositoryIDString.equals(repIdStrs.getClassDescValueRepId())) {
  737. // read the class either with the wrong RepId or the
  738. // correct RepId for the classDesc
  739. value = readClass();
  740. }
  741. else {
  742. Class valueClass = getClassFromString(repositoryIDString,
  743. codebase_URL);
  744. if ((valueClass != null) &&
  745. org.omg.CORBA.portable.IDLEntity.class.isAssignableFrom(valueClass)) {
  746. value = readIDLValue(indirection, repositoryIDString, valueClass, codebase_URL);
  747. } else {
  748. try {
  749. // cannot cache this since this value will be different
  750. if (valueHandler == null) {
  751. valueHandler = ORBUtility.createValueHandler(orb);
  752. }
  753. value = valueHandler.readValue(parent, indirection, valueClass,
  754. repositoryIDString, getCodeBase());
  755. } catch(Exception ex) {
  756. debugPrintThrowable(ex);
  757. throw new org.omg.CORBA.MARSHAL("Unable to read value from underlying bridge : "
  758. + ex.getMessage(),
  759. MinorCodes.VALUEHANDLER_READ_EXCEPTION,
  760. CompletionStatus.COMPLETED_MAYBE);
  761. } catch(Error e) {
  762. debugPrintThrowable(e);
  763. throw new org.omg.CORBA.MARSHAL("Unable to read value from underlying bridge : "
  764. + e.getMessage(),
  765. MinorCodes.VALUEHANDLER_READ_ERROR,
  766. CompletionStatus.COMPLETED_MAYBE);
  767. }
  768. }
  769. }
  770. handleEndOfValue();
  771. readEndTag();
  772. // Put into valueCache
  773. if (valueCache == null)
  774. valueCache = new CacheTable(false);
  775. valueCache.put(value, indirection);
  776. // allow for possible continuation chunk
  777. isChunked = saveIsChunked;
  778. start_block();
  779. return (java.io.Serializable)value;
  780. }
  781. }
  782. public Serializable read_value(Class expectedType) {
  783. // Read value tag
  784. int vType = readValueTag();
  785. if (vType == 0)
  786. return null; // value is null
  787. else if (vType == 0xffffffff) { // Indirection tag
  788. int indirection = read_long() + get_offset() - 4;
  789. if (valueCache != null && valueCache.containsVal(indirection))
  790. {
  791. java.io.Serializable cachedValue = (java.io.Serializable)valueCache.getKey(indirection);
  792. return cachedValue;
  793. }
  794. else {
  795. throw new IndirectionException(indirection);
  796. }
  797. }
  798. else {
  799. int indirection = get_offset() - 4;
  800. // end_block();
  801. boolean saveIsChunked = isChunked;
  802. isChunked = repIdUtil.isChunkedEncoding(vType);
  803. java.lang.Object value = null;
  804. String codebase_URL = null;
  805. if (repIdUtil.isCodeBasePresent(vType)){
  806. codebase_URL = read_codebase_URL();
  807. }
  808. // Read repository id
  809. String repositoryIDString = null;
  810. switch(repIdUtil.getTypeInfo(vType)){
  811. case RepositoryIdUtility.NO_TYPE_INFO :
  812. // Throw an exception if we have no repository ID info and
  813. // no expectedType to work with. Otherwise, how would we
  814. // know what to unmarshal?
  815. if (expectedType == null)
  816. throw new MARSHAL("Expected type null and no repository ID info",
  817. MinorCodes.EXPECTED_TYPE_NULL_AND_NO_REP_ID,
  818. CompletionStatus.COMPLETED_MAYBE);
  819. repositoryIDString = repIdStrs.createForAnyType(expectedType);
  820. break;
  821. case RepositoryIdUtility.SINGLE_REP_TYPE_INFO :
  822. repositoryIDString = read_repositoryId();
  823. break;
  824. case RepositoryIdUtility.PARTIAL_LIST_TYPE_INFO :
  825. repositoryIDString = read_repositoryIds();
  826. break;
  827. }
  828. // indirection = get_offset();
  829. start_block();
  830. end_flag--;
  831. if (isChunked)
  832. chunkedValueNestingLevel--;
  833. if (repositoryIDString.equals(repIdStrs.getWStringValueRepId()))
  834. {
  835. value = read_wstring();
  836. }
  837. else if (repositoryIDString.equals(repIdStrs.getClassDescValueRepId()))
  838. {
  839. // read in the class whether with the old ClassDesc or the
  840. // new one
  841. value = readClass();
  842. }
  843. else {
  844. Class valueClass = expectedType;
  845. // By this point, either the expectedType or repositoryIDString
  846. // is guaranteed to be non-null.
  847. if (expectedType == null ||
  848. !repositoryIDString.equals(repIdStrs.createForAnyType(expectedType))) {
  849. valueClass = getClassFromString(repositoryIDString,
  850. codebase_URL,
  851. expectedType);
  852. }
  853. if ((valueClass != null) &&
  854. org.omg.CORBA.portable.IDLEntity.class.isAssignableFrom(valueClass)) {
  855. value = readIDLValue(indirection, repositoryIDString, valueClass, codebase_URL);
  856. } else {
  857. try {
  858. if (valueHandler == null) {
  859. valueHandler = ORBUtility.createValueHandler(orb);
  860. }
  861. value = valueHandler.readValue(parent, indirection, valueClass,
  862. repositoryIDString, getCodeBase());
  863. } catch(Exception ex) {
  864. debugPrintThrowable(ex);
  865. throw new org.omg.CORBA.MARSHAL("Unable to read value from underlying bridge : "
  866. + ex.getMessage(),
  867. MinorCodes.VALUEHANDLER_READ_EXCEPTION,
  868. CompletionStatus.COMPLETED_MAYBE);
  869. } catch(Error e){
  870. debugPrintThrowable(e);
  871. throw new org.omg.CORBA.MARSHAL("Unable to read value from underlying bridge : "
  872. + e.getMessage(),
  873. MinorCodes.VALUEHANDLER_READ_ERROR,
  874. CompletionStatus.COMPLETED_MAYBE);
  875. }
  876. }
  877. }
  878. handleEndOfValue();
  879. readEndTag();
  880. // Put into valueCache
  881. if (valueCache == null)
  882. valueCache = new CacheTable(false);
  883. valueCache.put(value, indirection);
  884. // allow for possible continuation chunk
  885. isChunked = saveIsChunked;
  886. start_block();
  887. return (java.io.Serializable)value;
  888. }
  889. }
  890. public Serializable read_value(BoxedValueHelper factory) {
  891. // Read value tag
  892. int vType = readValueTag();
  893. if (vType == 0)
  894. return null; // value is null
  895. else if (vType == 0xffffffff) { // Indirection tag
  896. int indirection = read_long() + get_offset() - 4;
  897. if (valueCache != null && valueCache.containsVal(indirection))
  898. {
  899. java.io.Serializable cachedValue = (java.io.Serializable)valueCache.getKey(indirection);
  900. return cachedValue;
  901. }
  902. else {
  903. throw new IndirectionException(indirection);
  904. }
  905. }
  906. else {
  907. int indirection = get_offset() - 4;
  908. // end_block();
  909. boolean saveIsChunked = isChunked;
  910. isChunked = repIdUtil.isChunkedEncoding(vType);
  911. java.lang.Object value = null;
  912. String codebase_URL = null;
  913. if (repIdUtil.isCodeBasePresent(vType)){
  914. codebase_URL = read_codebase_URL();
  915. }
  916. // Read repository id
  917. String repositoryIDString = null;
  918. switch(repIdUtil.getTypeInfo(vType)){
  919. case RepositoryIdUtility.NO_TYPE_INFO :
  920. throw new org.omg.CORBA.MARSHAL("No class description available (value_tag indicates no type information present)");
  921. case RepositoryIdUtility.SINGLE_REP_TYPE_INFO :
  922. repositoryIDString = read_repositoryId();
  923. break;
  924. case RepositoryIdUtility.PARTIAL_LIST_TYPE_INFO :
  925. repositoryIDString = read_repositoryIds();
  926. break;
  927. }
  928. // Compare rep. ids to see if we should use passed helper
  929. if (!repositoryIDString.equals(factory.get_id()))
  930. factory = Utility.getHelper(null, codebase_URL, repositoryIDString);
  931. start_block();
  932. end_flag--;
  933. if (isChunked)
  934. chunkedValueNestingLevel--;
  935. if (factory instanceof ValueHelper) {
  936. value = readIDLValueWithHelper((ValueHelper)factory, indirection);
  937. } else {
  938. valueIndirection = indirection; // for callback
  939. value = factory.read_value(parent);
  940. }
  941. handleEndOfValue();
  942. readEndTag();
  943. // Put into valueCache
  944. if (valueCache == null)
  945. valueCache = new CacheTable(false);
  946. valueCache.put(value, indirection);
  947. // allow for possible continuation chunk
  948. isChunked = saveIsChunked;
  949. start_block();
  950. return (java.io.Serializable)value;
  951. }
  952. }
  953. private boolean isCustomType(ValueHelper helper) {
  954. try{
  955. TypeCode tc = helper.get_type();
  956. int kind = tc.kind().value();
  957. if (kind == TCKind._tk_value) {
  958. return (tc.type_modifier() == org.omg.CORBA.VM_CUSTOM.value);
  959. }
  960. }
  961. catch(BadKind ex) {
  962. throw new org.omg.CORBA.MARSHAL(MinorCodes.BAD_KIND,
  963. CompletionStatus.COMPLETED_MAYBE);
  964. }
  965. return false;
  966. }
  967. // This method is actually called indirectly by
  968. // read_value(String repositoryId).
  969. // Therefore, it is not a truly independent read call that handles
  970. // header information itself.
  971. public java.io.Serializable read_value(java.io.Serializable value) {
  972. // Put into valueCache using valueIndirection
  973. if (valueCache == null)
  974. valueCache = new CacheTable(false);
  975. valueCache.put(value, valueIndirection);
  976. if (value instanceof StreamableValue)
  977. ((StreamableValue)value)._read(parent);
  978. else if (value instanceof CustomValue)
  979. ((CustomValue)value).unmarshal(parent);
  980. return value;
  981. }
  982. public java.io.Serializable read_value(java.lang.String repositoryId) {
  983. // if (inBlock)
  984. // end_block();
  985. // Read value tag
  986. int vType = readValueTag();
  987. if (vType == 0)
  988. return null; // value is null
  989. else if (vType == 0xffffffff) { // Indirection tag
  990. int indirection = read_long() + get_offset() - 4;
  991. if (valueCache != null && valueCache.containsVal(indirection))
  992. {
  993. java.io.Serializable cachedValue = (java.io.Serializable)valueCache.getKey(indirection);
  994. return cachedValue;
  995. }
  996. else {
  997. throw new IndirectionException(indirection);
  998. }
  999. }
  1000. else {
  1001. int indirection = get_offset() - 4;
  1002. // end_block();
  1003. boolean saveIsChunked = isChunked;
  1004. isChunked = repIdUtil.isChunkedEncoding(vType);
  1005. java.lang.Object value = null;
  1006. String codebase_URL = null;
  1007. if (repIdUtil.isCodeBasePresent(vType)){
  1008. codebase_URL = read_codebase_URL();
  1009. }
  1010. // Read repository id
  1011. String repositoryIDString = null;
  1012. switch(repIdUtil.getTypeInfo(vType)){
  1013. case RepositoryIdUtility.NO_TYPE_INFO :
  1014. repositoryIDString = repositoryId;
  1015. break;
  1016. case RepositoryIdUtility.SINGLE_REP_TYPE_INFO :
  1017. repositoryIDString = read_repositoryId();
  1018. break;
  1019. case RepositoryIdUtility.PARTIAL_LIST_TYPE_INFO :
  1020. repositoryIDString = read_repositoryIds();
  1021. break;
  1022. }
  1023. ValueFactory factory = Utility.getFactory(null, codebase_URL, orb, repositoryIDString);
  1024. start_block();
  1025. end_flag--;
  1026. if (isChunked)
  1027. chunkedValueNestingLevel--;
  1028. valueIndirection = indirection; // for callback
  1029. value = factory.read_value(parent);
  1030. handleEndOfValue();
  1031. readEndTag();
  1032. // Put into valueCache
  1033. if (valueCache == null)
  1034. valueCache = new CacheTable(false);
  1035. valueCache.put(value, indirection);
  1036. // allow for possible continuation chunk
  1037. isChunked = saveIsChunked;
  1038. start_block();
  1039. return (java.io.Serializable)value;
  1040. }
  1041. }
  1042. private Class readClass() {
  1043. String codebases = null, classRepId = null;
  1044. if (orb == null ||
  1045. ORBVersionImpl.FOREIGN.equals(orb.getORBVersion()) ||
  1046. ORBVersionImpl.NEWER.compareTo(orb.getORBVersion()) <= 0) {
  1047. codebases = (String)read_value(java.lang.String.class);
  1048. classRepId = (String)read_value(java.lang.String.class);
  1049. } else {
  1050. // Pre-Merlin/J2EE 1.3 ORBs wrote the repository ID
  1051. // and codebase strings in the wrong order.
  1052. classRepId = (String)read_value(java.lang.String.class);
  1053. codebases = (String)read_value(java.lang.String.class);
  1054. }
  1055. if (debug) {
  1056. debugPrintMessage("readClass codebases: "
  1057. + codebases
  1058. + " rep Id: "
  1059. + classRepId);
  1060. }
  1061. Class cl = null;
  1062. RepositoryIdInterface repositoryID
  1063. = repIdStrs.getFromString(classRepId);
  1064. try {
  1065. cl = repositoryID.getClassFromType(codebases);
  1066. } catch(ClassNotFoundException cnfe){
  1067. debugPrintThrowable(cnfe);
  1068. throw new org.omg.CORBA.MARSHAL("Unable to load Class "
  1069. + repositoryID.getClassName()
  1070. + " : " + cnfe.getMessage(),
  1071. MinorCodes.CNFE_READ_CLASS,
  1072. CompletionStatus.COMPLETED_MAYBE);
  1073. }
  1074. catch(MalformedURLException me){
  1075. debugPrintThrowable(me);
  1076. throw new org.omg.CORBA.MARSHAL("Unable to load Class "
  1077. + repositoryID.getClassName()
  1078. + " : " + me.getMessage(),
  1079. MinorCodes.MALFORMED_URL,
  1080. CompletionStatus.COMPLETED_MAYBE);
  1081. }
  1082. return cl;
  1083. }
  1084. private java.lang.Object readIDLValueWithHelper(ValueHelper helper, int indirection) {
  1085. // look for two-argument static read method
  1086. Method readMethod;
  1087. try {
  1088. Class argTypes[] = {org.omg.CORBA.portable.InputStream.class, helper.get_class()};
  1089. readMethod = helper.getClass().getDeclaredMethod(kReadMethod, argTypes);
  1090. }
  1091. catch(NoSuchMethodException nsme) { // must be boxed value helper
  1092. java.lang.Object result = helper.read_value(parent);
  1093. return result;
  1094. }
  1095. // found two-argument read method, so must be non-boxed value...
  1096. // ...create a blank instance
  1097. java.lang.Object val = null;
  1098. try {
  1099. val = helper.get_class().newInstance();
  1100. }
  1101. catch(java.lang.InstantiationException ie){
  1102. debugPrintThrowable(ie);
  1103. throw new org.omg.CORBA.MARSHAL(ie.getMessage());
  1104. }
  1105. catch(IllegalAccessException iae){
  1106. // Value's constructor is protected or private
  1107. //
  1108. // So, use the helper to read the value.
  1109. //
  1110. // NOTE : This means that in this particular case a recursive ref.
  1111. // would fail.
  1112. return helper.read_value(parent);
  1113. }
  1114. // add blank instance to cache table
  1115. if (valueCache == null)
  1116. valueCache = new CacheTable(false);
  1117. valueCache.put(val, indirection);
  1118. // if custom type, call unmarshal method
  1119. if (val instanceof CustomMarshal && isCustomType(helper)) {
  1120. ((CustomMarshal)val).unmarshal(parent);
  1121. return val;
  1122. }
  1123. // call two-argument read method using reflection
  1124. try {
  1125. java.lang.Object args[] = {parent, val};
  1126. readMethod.invoke(helper, args);
  1127. return val;
  1128. }
  1129. catch(IllegalAccessException iae2){
  1130. debugPrintThrowable(iae2);
  1131. throw new org.omg.CORBA.MARSHAL(iae2.getMessage());
  1132. }
  1133. catch(InvocationTargetException ite){
  1134. debugPrintThrowable(ite);
  1135. throw new org.omg.CORBA.MARSHAL(ite.getMessage());
  1136. }
  1137. }
  1138. private java.lang.Object readBoxedIDLEntity(Class clazz, String codebase)
  1139. {
  1140. try {
  1141. ClassLoader clazzLoader = (clazz == null ? null : clazz.getClassLoader());
  1142. final Class helperClass = Utility.loadClassForClass(clazz.getName()+"Helper", codebase,
  1143. clazzLoader, clazz, clazzLoader);
  1144. final Class argTypes[] = {org.omg.CORBA.portable.InputStream.class};
  1145. // getDeclaredMethod requires RuntimePermission accessDeclaredMembers
  1146. // if a different class loader is used (even though the javadoc says otherwise)
  1147. Method readMethod = null;
  1148. try {
  1149. readMethod = (Method)AccessController.doPrivileged(
  1150. new PrivilegedExceptionAction() {
  1151. public java.lang.Object run() throws NoSuchMethodException {
  1152. return helperClass.getDeclaredMethod(kReadMethod, argTypes);
  1153. }
  1154. }
  1155. );
  1156. } catch (PrivilegedActionException pae) {
  1157. // this gets caught below
  1158. throw (NoSuchMethodException)pae.getException();
  1159. }
  1160. java.lang.Object args[] = {parent};
  1161. return readMethod.invoke(null, args);
  1162. } catch (ClassNotFoundException cnfe) {
  1163. debugPrintThrowable(cnfe);
  1164. throw new org.omg.CORBA.MARSHAL(cnfe.getMessage());
  1165. } catch(NoSuchMethodException nsme) {
  1166. debugPrintThrowable(nsme);
  1167. throw new org.omg.CORBA.MARSHAL(nsme.getMessage());
  1168. } catch(IllegalAccessException iae) {
  1169. debugPrintThrowable(iae);
  1170. throw new org.omg.CORBA.MARSHAL(iae.getMessage());
  1171. } catch(InvocationTargetException ite) {
  1172. debugPrintThrowable(ite);
  1173. throw new org.omg.CORBA.MARSHAL(ite.getMessage());
  1174. }
  1175. }
  1176. private java.lang.Object readIDLValue(int indirection, String repId,
  1177. Class clazz, String codebase)
  1178. {
  1179. if (StreamableValue.class.isAssignableFrom(clazz) ||
  1180. CustomValue.class.isAssignableFrom(clazz)) {
  1181. // use new-style OBV support (factory object)
  1182. ValueFactory factory = Utility.getFactory(clazz, codebase, orb, repId);
  1183. valueIndirection = indirection; // for callback
  1184. return factory.read_value(parent);
  1185. } else if (ValueBase.class.isAssignableFrom(clazz)) {
  1186. // use old-style OBV support (helper object)
  1187. BoxedValueHelper helper = Utility.getHelper(clazz, codebase, repId);
  1188. if (helper instanceof ValueHelper)
  1189. return readIDLValueWithHelper((ValueHelper)helper, indirection);
  1190. else
  1191. return helper.read_value(parent);
  1192. } else {
  1193. // must be a boxed IDLEntity, so make a reflective call to the
  1194. // helper's static read method...
  1195. return readBoxedIDLEntity(clazz, codebase);
  1196. }
  1197. }
  1198. /**
  1199. * End tags are only written for chunked valuetypes.
  1200. *
  1201. * Before Merlin, our ORBs wrote end tags which took into account
  1202. * all enclosing valuetypes. This was changed by an interop resolution
  1203. * (see details around chunkedValueNestingLevel) to only include
  1204. * enclosing chunked types.
  1205. *
  1206. * ORB versioning and end tag compaction are handled here.
  1207. */
  1208. private void readEndTag() {
  1209. if (isChunked) {
  1210. // Read the end tag
  1211. int anEndTag = read_long();
  1212. // End tags should always be negative, and the outermost
  1213. // enclosing chunked valuetype should have a -1 end tag.
  1214. if (anEndTag >= 0) {
  1215. if (anEndTag >= maxBlockLength) {
  1216. // A custom marshaled valuetype left extra data
  1217. // on the wire, and that data had another
  1218. // nested value inside of it. We've just
  1219. // read the value tag of that nested value.
  1220. //
  1221. // In an attempt to get by it, we'll try to call
  1222. // read_value() to get the nested value off of
  1223. // the wire. Afterwards, we must call handleEndOfValue
  1224. // to read any further chunks that the containing
  1225. // valuetype might still have after the nested
  1226. // value. Finally, we make a recursive call to
  1227. // readEndTag to read the end tag of the
  1228. // containing value, or do this again if there
  1229. // are more nested values.
  1230. bbwi.index -= 4;
  1231. read_value();
  1232. handleEndOfValue();
  1233. readEndTag();
  1234. return;
  1235. } else {
  1236. // We read something that wasn't big enough to be
  1237. // a value tag. This is an error.
  1238. throw new MARSHAL("Read non-negative end tag: "
  1239. + anEndTag + " at " + (get_offset() - 4),
  1240. MinorCodes.POSITIVE_END_TAG,
  1241. CompletionStatus.COMPLETED_MAYBE);
  1242. }
  1243. }
  1244. // If the ORB is null, or if we're sure we're talking to
  1245. // a foreign ORB, Merlin, or something more recent, we
  1246. // use the updated end tag computation, and are more strenuous
  1247. // about the values.
  1248. if (orb == null ||
  1249. ORBVersionImpl.FOREIGN.equals(orb.getORBVersion()) ||
  1250. ORBVersionImpl.NEWER.compareTo(orb.getORBVersion()) <= 0) {
  1251. // If the end tag we read was less than what we were expecting,
  1252. // then the sender must think it's sent more enclosing
  1253. // chunked valuetypes than we have. Throw an exception.
  1254. if (anEndTag < chunkedValueNestingLevel)
  1255. throw new MARSHAL("Expecting fewer enclosing valuetypes. "
  1256. + "Received end tag " + anEndTag
  1257. + " but expected " + chunkedValueNestingLevel,
  1258. MinorCodes.UNEXPECTED_ENCLOSING_VALUETYPE,
  1259. CompletionStatus.COMPLETED_MAYBE);
  1260. // If the end tag is bigger than what we expected, but
  1261. // still negative, then the sender has done some end tag
  1262. // compaction. We back up the stream 4 bytes so that the
  1263. // next time readEndTag is called, it will get down here
  1264. // again. Even with fragmentation, we'll always be able
  1265. // to do this.
  1266. if (anEndTag != chunkedValueNestingLevel)
  1267. bbwi.index -= 4;
  1268. } else {
  1269. // When talking to Kestrel or Ladybird, we use our old
  1270. // end tag rules and are less strict. If the end tag
  1271. // isn't what we expected, we back up, assuming
  1272. // compaction.
  1273. if (anEndTag != end_flag) {
  1274. bbwi.index -= 4;
  1275. }
  1276. }
  1277. // This only keeps track of the enclosing chunked
  1278. // valuetypes
  1279. chunkedValueNestingLevel++;
  1280. }
  1281. // This keeps track of all enclosing valuetypes
  1282. end_flag++;
  1283. }
  1284. protected int get_offset() {
  1285. return bbwi.index;
  1286. }
  1287. private void start_block() {
  1288. // if (outerValueDone)
  1289. if (!isChunked)
  1290. return;
  1291. // if called from alignAndCheck, need to reset blockLength
  1292. // to avoid an infinite recursion loop on read_long() call
  1293. blockLength = maxBlockLength;
  1294. blockLength = read_long();
  1295. // Must remember where we began the chunk to calculate how far
  1296. // along we are. See notes above about chunkBeginPos.
  1297. if ((blockLength > 0) && (blockLength < maxBlockLength)) {
  1298. blockLength += get_offset(); // _REVISIT_ unsafe, should use a Java long
  1299. // inBlock = true;
  1300. } else {
  1301. // not a chunk length field
  1302. blockLength = maxBlockLength;
  1303. bbwi.index -= 4;
  1304. }
  1305. }
  1306. // Makes sure that if we were reading a chunked value, we end up
  1307. // at the right place in the stream, no matter how little the
  1308. // unmarshalling code read
  1309. private void handleEndOfValue() {
  1310. if (!isChunked)
  1311. return;
  1312. while (blockLength != maxBlockLength) {
  1313. end_block();
  1314. start_block();
  1315. }
  1316. }
  1317. private void end_block() {
  1318. // if in a chunk, check for underflow or overflow
  1319. if (blockLength != maxBlockLength) {
  1320. if (blockLength == get_offset()) {
  1321. // Chunk ended correctly
  1322. blockLength = maxBlockLength;
  1323. } else {
  1324. // Skip over anything left by bad unmarshaling code (ex:
  1325. // a buggy custom unmarshaler). REVISIT This needs to be
  1326. // done for all remaining chunks in this value, right?
  1327. if (blockLength > get_offset()) {
  1328. skipToOffset(blockLength);
  1329. } else {
  1330. throw new MARSHAL("Incorrect chunk length "
  1331. + blockLength
  1332. + " at offset "
  1333. + get_offset(),
  1334. com.sun.corba.se.internal.orbutil.MinorCodes.CHUNK_OVERFLOW,
  1335. CompletionStatus.COMPLETED_NO);
  1336. }
  1337. }
  1338. }
  1339. }
  1340. private int readValueTag(){
  1341. // outerValueDone = false;
  1342. return read_long();
  1343. }
  1344. public org.omg.CORBA.ORB orb() {
  1345. return orb;
  1346. }
  1347. // ------------ End RMI related methods --------------------------
  1348. public final void read_boolean_array(boolean[] value, int offset, int length) {
  1349. for(int i=0; i < length; i++) {
  1350. value[i+offset] = read_boolean();
  1351. }
  1352. }
  1353. public final void read_char_array(char[] value, int offset, int length) {
  1354. for(int i=0; i < length; i++) {
  1355. value[i+offset] = read_char();
  1356. }
  1357. }
  1358. public final void read_wchar_array(char[] value, int offset, int length) {
  1359. for(int i=0; i < length; i++) {
  1360. value[i+offset] = read_wchar();
  1361. }
  1362. }
  1363. public final void read_short_array(short[] value, int offset, int length) {
  1364. for(int i=0; i < length; i++) {
  1365. value[i+offset] = read_short();
  1366. }
  1367. }
  1368. public final void read_ushort_array(short[] value, int offset, int length) {
  1369. read_short_array(value, offset, length);
  1370. }
  1371. public final void read_long_array(int[] value, int offset, int length) {
  1372. for(int i=0; i < length; i++) {
  1373. value[i+offset] = read_long();
  1374. }
  1375. }
  1376. public final void read_ulong_array(int[] value, int offset, int length) {
  1377. read_long_array(value, offset, length);
  1378. }
  1379. public final void read_longlong_array(long[] value, int offset, int length) {
  1380. for(int i=0; i < length; i++) {
  1381. value[i+offset] = read_longlong();
  1382. }
  1383. }
  1384. public final void read_ulonglong_array(long[] value, int offset, int length) {
  1385. read_longlong_array(value, offset, length);
  1386. }
  1387. public final void read_float_array(float[] value, int offset, int length) {
  1388. for(int i=0; i < length; i++) {
  1389. value[i+offset] = read_float();
  1390. }
  1391. }
  1392. public final void read_double_array(double[] value, int offset, int length) {
  1393. for(int i=0; i < length; i++) {
  1394. value[i+offset] = read_double();
  1395. }
  1396. }
  1397. public final void read_any_array(org.omg.CORBA.Any[] value, int offset, int length) {
  1398. for(int i=0; i < length; i++) {
  1399. value[i+offset] = read_any();
  1400. }
  1401. }
  1402. //--------------------------------------------------------------------//
  1403. // CDRInputStream state management.
  1404. //
  1405. /**
  1406. * Are we at the end of the input stream?
  1407. */
  1408. // public final boolean isAtEnd() {
  1409. // return bbwi.index == bbwi.buflen;
  1410. // }
  1411. // public int available() throws IOException {
  1412. // return bbwi.buflen - bbwi.index;
  1413. // }
  1414. private String read_repositoryIds() {
  1415. // Read # of repository ids
  1416. int numRepIds = read_long();
  1417. if (numRepIds == 0xffffffff) {
  1418. int indirection = read_long() + get_offset() - 4;
  1419. if (repositoryIdCache != null && repositoryIdCache.containsOrderedVal(indirection))
  1420. return (String)repositoryIdCache.getKey(indirection);
  1421. else
  1422. throw new org.omg.CORBA.MARSHAL("Unable to locate array of repository IDs from indirection "
  1423. + indirection);
  1424. } else {
  1425. // read first array element and store it as an indirection to the whole array
  1426. int indirection = get_offset();
  1427. String repID = read_repositoryId();
  1428. if (repositoryIdCache == null)
  1429. repositoryIdCache = new CacheTable(false);
  1430. repositoryIdCache.put(repID, indirection);
  1431. // read and ignore the subsequent array elements, but put them in the
  1432. // indirection table in case there are later indirections back to them
  1433. for (int i = 1; i < numRepIds; i++) {
  1434. read_repositoryId();
  1435. }
  1436. return repID;
  1437. }
  1438. }
  1439. private final String read_repositoryId() {
  1440. String result = readStringOrIndirection(true);
  1441. if (result == null) { // Indirection
  1442. int indirection = read_long() + get_offset() - 4;
  1443. if (repositoryIdCache != null && repositoryIdCache.containsOrderedVal(indirection))
  1444. return (String)repositoryIdCache.getKey(indirection);
  1445. else
  1446. throw new org.omg.CORBA.MARSHAL("Repid indirection @ " + bbwi.index,
  1447. MinorCodes.BAD_REP_ID_INDIRECTION,
  1448. CompletionStatus.COMPLETED_MAYBE);
  1449. } else {
  1450. if (repositoryIdCache == null)
  1451. repositoryIdCache = new CacheTable(false);
  1452. repositoryIdCache.put(result, stringIndirection);
  1453. return result;
  1454. }
  1455. }
  1456. private final String read_codebase_URL() {
  1457. String result = readStringOrIndirection(true);
  1458. if (result == null) { // Indirection
  1459. int indirection = read_long() + get_offset() - 4;
  1460. if (codebaseCache != null && codebaseCache.containsVal(indirection))
  1461. return (String)codebaseCache.getKey(indirection);
  1462. else
  1463. throw new org.omg.CORBA.MARSHAL("Codebase indirection @ " + bbwi.index,
  1464. MinorCodes.BAD_CODEBASE_INDIRECTION,
  1465. CompletionStatus.COMPLETED_MAYBE);
  1466. } else {
  1467. if (codebaseCache == null)
  1468. codebaseCache = new CacheTable(false);
  1469. codebaseCache.put(result, stringIndirection);
  1470. return result;
  1471. }
  1472. }
  1473. /* DataInputStream methods */
  1474. public java.lang.Object read_Abstract () {
  1475. return read_abstract_interface();
  1476. }
  1477. public java.io.Serializable read_Value () {
  1478. return read_value();
  1479. }
  1480. public void read_any_array (org.omg.CORBA.AnySeqHolder seq, int offset, int length) {
  1481. read_any_array(seq.value, offset, length);
  1482. }
  1483. public void read_boolean_array (org.omg.CORBA.BooleanSeqHolder seq, int offset, int length) {
  1484. read_boolean_array(seq.value, offset, length);
  1485. }
  1486. public void read_char_array (org.omg.CORBA.CharSeqHolder seq, int offset, int length) {
  1487. read_char_array(seq.value, offset, length);
  1488. }
  1489. public void read_wchar_array (org.omg.CORBA.WCharSeqHolder seq, int offset, int length) {
  1490. read_wchar_array(seq.value, offset, length);
  1491. }
  1492. public void read_octet_array (org.omg.CORBA.OctetSeqHolder seq, int offset, int length) {
  1493. read_octet_array(seq.value, offset, length);
  1494. }
  1495. public void read_short_array (org.omg.CORBA.ShortSeqHolder seq, int offset, int length) {
  1496. read_short_array(seq.value, offset, length);
  1497. }
  1498. public void read_ushort_array (org.omg.CORBA.UShortSeqHolder seq, int offset, int length) {
  1499. read_ushort_array(seq.value, offset, length);
  1500. }
  1501. public void read_long_array (org.omg.CORBA.LongSeqHolder seq, int offset, int length) {
  1502. read_long_array(seq.value, offset, length);
  1503. }
  1504. public void read_ulong_array (org.omg.CORBA.ULongSeqHolder seq, int offset, int length) {
  1505. read_ulong_array(seq.value, offset, length);
  1506. }
  1507. public void read_ulonglong_array (org.omg.CORBA.ULongLongSeqHolder seq, int offset, int length) {
  1508. read_ulonglong_array(seq.value, offset, length);
  1509. }
  1510. public void read_longlong_array (org.omg.CORBA.LongLongSeqHolder seq, int offset, int length) {
  1511. read_longlong_array(seq.value, offset, length);
  1512. }
  1513. public void read_float_array (org.omg.CORBA.FloatSeqHolder seq, int offset, int length) {
  1514. read_float_array(seq.value, offset, length);
  1515. }
  1516. public void read_double_array (org.omg.CORBA.DoubleSeqHolder seq, int offset, int length) {
  1517. read_double_array(seq.value, offset, length);
  1518. }
  1519. public java.math.BigDecimal read_fixed(short digits, short scale) {
  1520. // digits isn't really needed here
  1521. StringBuffer buffer = read_fixed_buffer();
  1522. if (digits != buffer.length())
  1523. throw new MARSHAL();
  1524. buffer.insert(digits - scale, '.');
  1525. return new BigDecimal(buffer.toString());
  1526. }
  1527. // This method is unable to yield the correct scale.
  1528. public java.math.BigDecimal read_fixed() {
  1529. return new BigDecimal(read_fixed_buffer().toString());
  1530. }
  1531. // Each octet contains (up to) two decimal digits.
  1532. // If the fixed type has an odd number of decimal digits, then the representation
  1533. // begins with the first (most significant) digit.
  1534. // Otherwise, this first half-octet is all zero, and the first digit
  1535. // is in the second half-octet.
  1536. // The sign configuration, in the last half-octet of the representation,
  1537. // is 0xD for negative numbers and 0xC for positive and zero values.
  1538. private StringBuffer read_fixed_buffer() {
  1539. StringBuffer buffer = new StringBuffer(64);
  1540. byte doubleDigit;
  1541. int firstDigit;
  1542. int secondDigit;
  1543. boolean wroteFirstDigit = false;
  1544. boolean more = true;
  1545. while (more) {
  1546. doubleDigit = this.read_octet();
  1547. firstDigit = (int)((doubleDigit & 0xf0) >> 4);
  1548. secondDigit = (int)(doubleDigit & 0x0f);
  1549. if (wroteFirstDigit || firstDigit != 0) {
  1550. buffer.append(Character.forDigit(firstDigit, 10));
  1551. wroteFirstDigit = true;
  1552. }
  1553. if (secondDigit == 12) {
  1554. // positive number or zero
  1555. if ( ! wroteFirstDigit) {
  1556. // zero
  1557. return new StringBuffer("0.0");
  1558. } else {
  1559. // positive number
  1560. // done
  1561. }
  1562. more = false;
  1563. } else if (secondDigit == 13) {
  1564. // negative number
  1565. buffer.insert(0, '-');
  1566. more = false;
  1567. } else {
  1568. buffer.append(Character.forDigit(secondDigit, 10));
  1569. wroteFirstDigit = true;
  1570. }
  1571. }
  1572. return buffer;
  1573. }
  1574. private final static String _id = "IDL:omg.org/CORBA/DataInputStream:1.0";
  1575. private final static String[] _ids = { _id };
  1576. public String[] _truncatable_ids() {
  1577. if (_ids == null)
  1578. return null;
  1579. return (String[])_ids.clone();
  1580. }
  1581. /* for debugging */
  1582. public void printBuffer() {
  1583. CDRInputStream_1_0.printBuffer(this.bbwi);
  1584. }
  1585. public static void printBuffer(ByteBufferWithInfo bbwi) {
  1586. System.out.println("----- Input Buffer -----");
  1587. System.out.println();
  1588. System.out.println("Current index: " + bbwi.index);
  1589. System.out.println("Total length : " + bbwi.buflen);
  1590. System.out.println();
  1591. try {
  1592. char[] charBuf = new char[16];
  1593. for (int i = 0; i < bbwi.buflen; i += 16) {
  1594. int j = 0;
  1595. // For every 16 bytes, there is one line
  1596. // of output. First, the hex output of
  1597. // the 16 bytes with each byte separated
  1598. // by a space.
  1599. while (j < 16 && j + i < bbwi.buflen) {
  1600. int k = bbwi.buf[i + j];
  1601. if (k < 0)
  1602. k = 256 + k;
  1603. String hex = Integer.toHexString(k);
  1604. if (hex.length() == 1)
  1605. hex = "0" + hex;
  1606. System.out.print(hex + " ");
  1607. j++;
  1608. }
  1609. // Add any extra spaces to align the
  1610. // text column in case we didn't end
  1611. // at 16
  1612. while (j < 16) {
  1613. System.out.print(" ");
  1614. j++;
  1615. }
  1616. // Now output the ASCII equivalents. Non-ASCII
  1617. // characters are shown as periods.
  1618. int x = 0;
  1619. while (x < 16 && x + i < bbwi.buflen) {
  1620. if (Character.isLetterOrDigit((char)bbwi.buf[i + x]))
  1621. charBuf[x] = (char)bbwi.buf[i + x];
  1622. else
  1623. charBuf[x] = '.';
  1624. x++;
  1625. }
  1626. System.out.println(new String(charBuf, 0, x));
  1627. }
  1628. } catch (Throwable t) {
  1629. t.printStackTrace();
  1630. }
  1631. System.out.println("------------------------");
  1632. }
  1633. public byte[] getByteBuffer() {
  1634. return bbwi.buf;
  1635. }
  1636. public void setByteBuffer(byte buffer[]) {
  1637. bbwi.buf = buffer;
  1638. }
  1639. public int getBufferLength() {
  1640. return bbwi.buflen;
  1641. }
  1642. public void setBufferLength(int value) {
  1643. bbwi.buflen = value;
  1644. }
  1645. public int getIndex() {
  1646. return bbwi.index;
  1647. }
  1648. public void setIndex(int value) {
  1649. bbwi.index = value;
  1650. }
  1651. public boolean isLittleEndian() {
  1652. return littleEndian;
  1653. }
  1654. public void orb(org.omg.CORBA.ORB orb) {
  1655. this.orb = (com.sun.corba.se.internal.corba.ORB)orb;
  1656. }
  1657. public BufferManagerRead getBufferManager() {
  1658. return bufferManagerRead;
  1659. }
  1660. private void skipToOffset(int offset) {
  1661. // Number of bytes to skip
  1662. int len = offset - get_offset();
  1663. int n = 0;
  1664. while (n < len) {
  1665. int avail;
  1666. int bytes;
  1667. int wanted;
  1668. avail = bbwi.buflen - bbwi.index;
  1669. if (avail <= 0) {
  1670. grow(1, 1);
  1671. avail = bbwi.buflen - bbwi.index;
  1672. }
  1673. wanted = len - n;
  1674. bytes = (wanted < avail) ? wanted : avail;
  1675. bbwi.index += bytes;
  1676. n += bytes;
  1677. }
  1678. }
  1679. // Mark and reset -------------------------------------------------
  1680. protected MarkAndResetHandler markAndResetHandler = null;
  1681. protected class StreamMemento
  1682. {
  1683. // These are the fields that may change after marking
  1684. // the stream position, so we need to save them.
  1685. private int blockLength_;
  1686. private int end_flag_;
  1687. private int chunkedValueNestingLevel_;
  1688. private int valueIndirection_;
  1689. private int stringIndirection_;
  1690. private boolean isChunked_;
  1691. private javax.rmi.CORBA.ValueHandler valueHandler_;
  1692. private ByteBufferWithInfo bbwi_;
  1693. public StreamMemento()
  1694. {
  1695. blockLength_ = blockLength;
  1696. end_flag_ = end_flag;
  1697. chunkedValueNestingLevel_ = chunkedValueNestingLevel;
  1698. valueIndirection_ = valueIndirection;
  1699. stringIndirection_ = stringIndirection;
  1700. isChunked_ = isChunked;
  1701. valueHandler_ = valueHandler;
  1702. bbwi_ = new ByteBufferWithInfo(bbwi);
  1703. }
  1704. }
  1705. public java.lang.Object createStreamMemento() {
  1706. return new StreamMemento();
  1707. }
  1708. public void restoreInternalState(java.lang.Object streamMemento) {
  1709. StreamMemento mem = (StreamMemento)streamMemento;
  1710. blockLength = mem.blockLength_;
  1711. end_flag = mem.end_flag_;
  1712. chunkedValueNestingLevel = mem.chunkedValueNestingLevel_;
  1713. valueIndirection = mem.valueIndirection_;
  1714. stringIndirection = mem.stringIndirection_;
  1715. isChunked = mem.isChunked_;
  1716. valueHandler = mem.valueHandler_;
  1717. bbwi = mem.bbwi_;
  1718. }
  1719. public int getPosition() {
  1720. return get_offset();
  1721. }
  1722. public void mark(int readlimit) {
  1723. markAndResetHandler.mark(this);
  1724. }
  1725. public void reset() {
  1726. markAndResetHandler.reset();
  1727. }
  1728. // ---------------------------------- end Mark and Reset
  1729. // Provides a hook so subclasses of CDRInputStream can provide
  1730. // a CodeBase. This ultimately allows us to grab a Connection
  1731. // instance in IIOPInputStream, the only subclass where this
  1732. // is actually used.
  1733. CodeBase getCodeBase() {
  1734. return parent.getCodeBase();
  1735. }
  1736. /**
  1737. * Attempts to find the class described by the given
  1738. * repository ID string and expected type. The first
  1739. * attempt is to find the class locally, falling back
  1740. * on the URL that came with the value. The second
  1741. * attempt is to use a URL from the remote CodeBase.
  1742. */
  1743. private Class getClassFromString(String repositoryIDString,
  1744. String codebaseURL,
  1745. Class expectedType)
  1746. {
  1747. RepositoryIdInterface repositoryID
  1748. = repIdStrs.getFromString(repositoryIDString);
  1749. try {
  1750. try {
  1751. // First try to load the class locally, then use
  1752. // the provided URL (if it isn't null)
  1753. return repositoryID.getClassFromType(expectedType,
  1754. codebaseURL);
  1755. } catch (ClassNotFoundException cnfeOuter) {
  1756. try {
  1757. // Get a URL from the remote CodeBase and retry
  1758. codebaseURL = getCodeBase().implementation(repositoryIDString);
  1759. // Don't bother trying to find it locally again if
  1760. // we got a null URL
  1761. if (codebaseURL == null)
  1762. return null;
  1763. return repositoryID.getClassFromType(expectedType,
  1764. codebaseURL);
  1765. } catch (ClassNotFoundException cnfeInner) {
  1766. debugPrintThrowable(cnfeInner);
  1767. // Failed to load the class
  1768. return null;
  1769. }
  1770. }
  1771. } catch (MalformedURLException mue) {
  1772. debugPrintThrowable(mue);
  1773. // Always report a bad URL
  1774. throw new MARSHAL("Unable to locate value class for rep. id : "
  1775. + repositoryIDString +
  1776. " because of malformed URL "
  1777. + codebaseURL,
  1778. MinorCodes.MALFORMED_URL,
  1779. CompletionStatus.COMPLETED_MAYBE);
  1780. }
  1781. }
  1782. /**
  1783. * Attempts to find the class described by the given
  1784. * repository ID string. At most, three attempts are made:
  1785. * Try to find it locally, through the provided URL, and
  1786. * finally, via a URL from the remote CodeBase.
  1787. */
  1788. private Class getClassFromString(String repositoryIDString,
  1789. String codebaseURL)
  1790. {
  1791. RepositoryIdInterface repositoryID
  1792. = repIdStrs.getFromString(repositoryIDString);
  1793. for (int i = 0; i < 3; i++) {
  1794. try {
  1795. switch (i)
  1796. {
  1797. case 0:
  1798. // First try to load the class locally
  1799. return repositoryID.getClassFromType();
  1800. case 1:
  1801. // Try to load the class using the provided
  1802. // codebase URL (falls out below)
  1803. break;
  1804. case 2:
  1805. // Try to load the class using a URL from the
  1806. // remote CodeBase
  1807. codebaseURL = getCodeBase().implementation(repositoryIDString);
  1808. break;
  1809. }
  1810. // Don't bother if the codebaseURL is null
  1811. if (codebaseURL == null)
  1812. continue;
  1813. return repositoryID.getClassFromType(codebaseURL);
  1814. } catch(ClassNotFoundException cnfe) {
  1815. // Will ultimately return null if all three
  1816. // attempts fail, but don't do anything here.
  1817. } catch (MalformedURLException mue) {
  1818. debugPrintThrowable(mue);
  1819. // Always report a bad URL
  1820. throw new MARSHAL("Unable to locate value class for rep. id : "
  1821. + repositoryIDString +
  1822. " because of malformed URL "
  1823. + codebaseURL,
  1824. MinorCodes.MALFORMED_URL,
  1825. CompletionStatus.COMPLETED_MAYBE);
  1826. }
  1827. }
  1828. // If we get here, we have failed to load the class
  1829. debugPrintMessage("getClassFromString failed with rep id "
  1830. + repositoryIDString
  1831. + " and codebase "
  1832. + codebaseURL);
  1833. return null;
  1834. }
  1835. // Utility method used to get chars from bytes
  1836. char[] getConvertedChars(int numBytes,
  1837. CodeSetConversion.BTCConverter converter) {
  1838. // To be honest, I doubt this saves much real time
  1839. if (bbwi.buflen - bbwi.index >= numBytes) {
  1840. // If the entire string is in this buffer,
  1841. // just convert directly from the bbwi rather than
  1842. // allocating and copying.
  1843. char[] result = converter.getChars(bbwi.buf, bbwi.index, numBytes);
  1844. bbwi.index += numBytes;
  1845. return result;
  1846. } else {
  1847. // Stretches across buffers. Unless we provide an
  1848. // incremental conversion interface, allocate and
  1849. // copy the bytes.
  1850. byte[] bytes = new byte[numBytes];
  1851. read_octet_array(bytes, 0, bytes.length);
  1852. return converter.getChars(bytes, 0, numBytes);
  1853. }
  1854. }
  1855. protected CodeSetConversion.BTCConverter getCharConverter() {
  1856. if (charConverter == null)
  1857. charConverter = parent.createCharBTCConverter();
  1858. return charConverter;
  1859. }
  1860. protected CodeSetConversion.BTCConverter getWCharConverter() {
  1861. if (wcharConverter == null)
  1862. wcharConverter = parent.createWCharBTCConverter();
  1863. return wcharConverter;
  1864. }
  1865. protected void debugPrintThrowable(Throwable t) {
  1866. if (debug && t != null)
  1867. t.printStackTrace();
  1868. }
  1869. protected void debugPrintMessage(String msg) {
  1870. if (debug)
  1871. ORBUtility.dprint(this, msg);
  1872. }
  1873. /**
  1874. * Aligns the current position on the given octet boundary
  1875. * if there are enough bytes available to do so. Otherwise,
  1876. * it just returns. This is used for some (but not all)
  1877. * GIOP 1.2 message headers.
  1878. */
  1879. void alignOnBoundary(int octetBoundary) {
  1880. int needed = computeAlignment(octetBoundary);
  1881. if (bbwi.index + needed <= bbwi.buflen)
  1882. bbwi.index += needed;
  1883. }
  1884. public void resetCodeSetConverters() {
  1885. charConverter = null;
  1886. wcharConverter = null;
  1887. }
  1888. }