1. /*
  2. * @(#)ValueHandlerImpl.java 1.44 03/01/23
  3. *
  4. * Copyright 2003 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.io;
  16. import javax.rmi.CORBA.Util;
  17. import javax.rmi.PortableRemoteObject;
  18. import java.util.Hashtable;
  19. import java.util.Stack;
  20. import java.io.IOException;
  21. import java.util.EmptyStackException;
  22. import com.sun.corba.se.internal.util.Utility;
  23. import com.sun.corba.se.internal.io.IIOPInputStream;
  24. import com.sun.corba.se.internal.io.IIOPOutputStream;
  25. import com.sun.corba.se.internal.util.MinorCodes;
  26. import com.sun.corba.se.internal.util.RepositoryId;
  27. import com.sun.corba.se.internal.util.Utility;
  28. import org.omg.CORBA.TCKind;
  29. import org.omg.CORBA.MARSHAL;
  30. import org.omg.CORBA.CompletionStatus;
  31. import org.omg.CORBA.portable.IndirectionException;
  32. import com.sun.org.omg.SendingContext.CodeBase;
  33. import com.sun.org.omg.SendingContext.CodeBaseHelper;
  34. import java.security.AccessController;
  35. import java.security.PrivilegedAction;
  36. import com.sun.corba.se.internal.io.IIOPInputStream.ActiveRecursionManager;
  37. public class ValueHandlerImpl implements javax.rmi.CORBA.ValueHandler {
  38. public static final short kRemoteType = 0;
  39. public static final short kAbstractType = 1;
  40. public static final short kValueType = 2;
  41. private Hashtable inputStreamPairs = null;
  42. private Hashtable outputStreamPairs = null;
  43. private CodeBase codeBase = null;
  44. private static boolean libraryManagerLoaded = false;
  45. private boolean useHashtables = true;
  46. private boolean isInputStream = true;
  47. private IIOPOutputStream outputStreamBridge = null;
  48. private IIOPInputStream inputStreamBridge = null;
  49. public ValueHandlerImpl(){
  50. if (!libraryManagerLoaded) {
  51. com.sun.corba.se.internal.io.LibraryManager.load();
  52. libraryManagerLoaded = true;
  53. }
  54. }
  55. public ValueHandlerImpl(boolean isInputStream) {
  56. this();
  57. useHashtables = false;
  58. this.isInputStream = isInputStream;
  59. }
  60. /**
  61. * Writes the value to the stream using java semantics.
  62. * @param out The stream to write the value to
  63. * @param value The value to be written to the stream
  64. **/
  65. public void writeValue(org.omg.CORBA.portable.OutputStream _out, java.io.Serializable value) {
  66. org.omg.CORBA_2_3.portable.OutputStream out =
  67. (org.omg.CORBA_2_3.portable.OutputStream) _out;
  68. if (!useHashtables)
  69. {
  70. if (outputStreamBridge == null)
  71. {
  72. outputStreamBridge = createOutputStream();
  73. outputStreamBridge.setOrbStream(out);
  74. }
  75. try {
  76. outputStreamBridge.increaseRecursionDepth();
  77. writeValueInternal(outputStreamBridge, out, value);
  78. }
  79. finally
  80. {
  81. outputStreamBridge.decreaseRecursionDepth();
  82. }
  83. return;
  84. }
  85. IIOPOutputStream jdkToOrbOutputStreamBridge = null;
  86. if (outputStreamPairs == null)
  87. outputStreamPairs = new Hashtable();
  88. jdkToOrbOutputStreamBridge = (IIOPOutputStream)outputStreamPairs.get(_out);
  89. if (jdkToOrbOutputStreamBridge == null)
  90. {
  91. jdkToOrbOutputStreamBridge = createOutputStream();
  92. jdkToOrbOutputStreamBridge.setOrbStream(out);
  93. outputStreamPairs.put(_out, jdkToOrbOutputStreamBridge);
  94. }
  95. try {
  96. jdkToOrbOutputStreamBridge.increaseRecursionDepth();
  97. writeValueInternal(jdkToOrbOutputStreamBridge, out, value);
  98. }
  99. finally
  100. {
  101. if (jdkToOrbOutputStreamBridge.decreaseRecursionDepth() == 0)
  102. {
  103. outputStreamPairs.remove(_out);
  104. }
  105. }
  106. }
  107. private void writeValueInternal(IIOPOutputStream bridge,
  108. org.omg.CORBA_2_3.portable.OutputStream out,
  109. java.io.Serializable value)
  110. {
  111. Class clazz = value.getClass();
  112. if (clazz.isArray())
  113. write_Array(out, value, clazz.getComponentType());
  114. else
  115. bridge.simpleWriteObject(value);
  116. }
  117. /**
  118. * Reads a value from the stream using java semantics.
  119. * @param in The stream to read the value from
  120. * @param clazz The type of the value to be read in
  121. * @param sender The sending context runtime
  122. **/
  123. public java.io.Serializable readValue(org.omg.CORBA.portable.InputStream _in,
  124. int offset,
  125. java.lang.Class clazz,
  126. String repositoryID,
  127. org.omg.SendingContext.RunTime _sender)
  128. {
  129. // Must use narrow rather than a direct cast to a com.sun
  130. // class. Fix for bug 4379539.
  131. CodeBase sender = CodeBaseHelper.narrow(_sender);
  132. org.omg.CORBA_2_3.portable.InputStream in =
  133. (org.omg.CORBA_2_3.portable.InputStream) _in;
  134. if (!useHashtables)
  135. {
  136. if (inputStreamBridge == null)
  137. {
  138. inputStreamBridge = createInputStream();
  139. inputStreamBridge.setOrbStream(in);
  140. inputStreamBridge.setSender(sender); //d11638
  141. // backward compatability 4365188
  142. inputStreamBridge.setValueHandler(this);
  143. }
  144. java.io.Serializable result = null;
  145. try {
  146. inputStreamBridge.increaseRecursionDepth();
  147. result = (java.io.Serializable) readValueInternal(inputStreamBridge, in, offset, clazz, repositoryID, sender);
  148. }
  149. finally
  150. {
  151. if (inputStreamBridge.decreaseRecursionDepth() == 0)
  152. {
  153. // Indirections are resolved immediately since
  154. // the change to the active recursion manager,
  155. // so this will never happen.
  156. //
  157. //if (!inputStreamBridge.recursionManager.isEmpty())
  158. // throw new org.omg.CORBA.MARSHAL("Dangling recursive references");
  159. }
  160. }
  161. return result;
  162. }
  163. IIOPInputStream jdkToOrbInputStreamBridge = null;
  164. if (inputStreamPairs == null)
  165. inputStreamPairs = new Hashtable();
  166. jdkToOrbInputStreamBridge = (IIOPInputStream)inputStreamPairs.get(_in);
  167. if (jdkToOrbInputStreamBridge == null)
  168. {
  169. jdkToOrbInputStreamBridge = createInputStream();
  170. jdkToOrbInputStreamBridge.setOrbStream(in);
  171. jdkToOrbInputStreamBridge.setSender(sender); //d11638
  172. // backward compatability 4365188
  173. jdkToOrbInputStreamBridge.setValueHandler(this);
  174. inputStreamPairs.put(_in, jdkToOrbInputStreamBridge);
  175. }
  176. java.io.Serializable result = null;
  177. try {
  178. jdkToOrbInputStreamBridge.increaseRecursionDepth();
  179. result = (java.io.Serializable) readValueInternal(jdkToOrbInputStreamBridge, in, offset, clazz, repositoryID, sender);
  180. }
  181. finally
  182. {
  183. if (jdkToOrbInputStreamBridge.decreaseRecursionDepth() == 0)
  184. {
  185. inputStreamPairs.remove(_in);
  186. }
  187. }
  188. return result;
  189. }
  190. private java.io.Serializable readValueInternal(IIOPInputStream bridge,
  191. org.omg.CORBA_2_3.portable.InputStream in,
  192. int offset,
  193. java.lang.Class clazz,
  194. String repositoryID,
  195. com.sun.org.omg.SendingContext.CodeBase sender)
  196. {
  197. java.io.Serializable result = null;
  198. if (clazz == null) {
  199. // clazz == null indicates an FVD situation for a nonexistant class
  200. if (isArray(repositoryID)){
  201. read_Array(bridge, in, null, sender, offset);
  202. } else {
  203. bridge.simpleSkipObject(repositoryID, sender);
  204. }
  205. return result;
  206. }
  207. if (clazz.isArray())
  208. {
  209. result = (java.io.Serializable)read_Array(bridge, in, clazz, sender, offset);
  210. } else
  211. {
  212. result = (java.io.Serializable)bridge.simpleReadObject(clazz, repositoryID, sender, offset);
  213. }
  214. if (result != null)
  215. {
  216. // bridge.recursionManager.handleRecursions(offset, result);
  217. }
  218. return result;
  219. }
  220. /**
  221. * Returns the repository ID for the given RMI value Class.
  222. * @param clz The class to return a repository ID for.
  223. * @return the repository ID of the Class.
  224. **/
  225. public java.lang.String getRMIRepositoryID(java.lang.Class clz) {
  226. return RepositoryId.createForJavaType(clz);
  227. }
  228. /**
  229. * Indicates whether the given Class performs custom or
  230. * default marshaling.
  231. * @param clz The class to test for custom marshaling.
  232. * @return True if the class performs custom marshaling, false
  233. * if it does not.
  234. **/
  235. public boolean isCustomMarshaled(java.lang.Class clz) {
  236. return ObjectStreamClass.lookup(clz).isCustomMarshaled();
  237. }
  238. /**
  239. * Returns the CodeBase for this ValueHandler. This is used by
  240. * the ORB runtime. The server sends the service context containing
  241. * the IOR for this CodeBase on the first GIOP reply. The clients
  242. * do the same on the first GIOP request.
  243. * @return the SendingContext.CodeBase of this ValueHandler.
  244. **/
  245. public org.omg.SendingContext.RunTime getRunTimeCodeBase() {
  246. if (codeBase != null)
  247. return codeBase;
  248. else {
  249. codeBase = new FVDCodeBaseImpl();
  250. // backward compatability 4365188
  251. // set the valueHandler so that correct/incorrect RepositoryID
  252. // calculations can be done based on the ORB version
  253. FVDCodeBaseImpl fvdImpl = (FVDCodeBaseImpl) codeBase;
  254. fvdImpl.setValueHandler(this);
  255. return codeBase;
  256. }
  257. }
  258. // methods supported for backward compatability so that the appropriate
  259. // Rep-id calculations take place based on the ORB version
  260. /**
  261. * Returns a boolean of whether or not RepositoryId indicates
  262. * FullValueDescriptor.
  263. * used for backward compatability
  264. */
  265. public boolean useFullValueDescription(Class clazz, String repositoryID)
  266. throws IOException
  267. {
  268. return RepositoryId.useFullValueDescription(clazz, repositoryID);
  269. }
  270. public String getClassName(String id)
  271. {
  272. RepositoryId repID = RepositoryId.cache.getId(id);
  273. return repID.getClassName();
  274. }
  275. public Class getClassFromType(String id)
  276. throws ClassNotFoundException
  277. {
  278. RepositoryId repId = RepositoryId.cache.getId(id);
  279. return repId.getClassFromType();
  280. }
  281. public Class getAnyClassFromType(String id)
  282. throws ClassNotFoundException
  283. {
  284. RepositoryId repId = RepositoryId.cache.getId(id);
  285. return repId.getAnyClassFromType();
  286. }
  287. public String createForAnyType(Class cl)
  288. {
  289. return RepositoryId.createForAnyType(cl);
  290. }
  291. public String getDefinedInId(String id)
  292. {
  293. RepositoryId repId = RepositoryId.cache.getId(id);
  294. return repId.getDefinedInId();
  295. }
  296. public String getUnqualifiedName(String id)
  297. {
  298. RepositoryId repId = RepositoryId.cache.getId(id);
  299. return repId.getUnqualifiedName();
  300. }
  301. public String getSerialVersionUID(String id)
  302. {
  303. RepositoryId repId = RepositoryId.cache.getId(id);
  304. return repId.getSerialVersionUID();
  305. }
  306. public boolean isAbstractBase(Class clazz)
  307. {
  308. return RepositoryId.isAbstractBase(clazz);
  309. }
  310. public boolean isSequence(String id)
  311. {
  312. RepositoryId repId = RepositoryId.cache.getId(id);
  313. return repId.isSequence();
  314. }
  315. /**
  316. * If the value contains a writeReplace method then the result
  317. * is returned. Otherwise, the value itself is returned.
  318. * @return the true value to marshal on the wire.
  319. **/
  320. public java.io.Serializable writeReplace(java.io.Serializable value) {
  321. return ObjectStreamClass.lookup(value.getClass()).writeReplace(value);
  322. }
  323. /**
  324. * Encapsulates writing of Java char arrays so that the 1.3 subclass
  325. * can override it without exposing internals across packages. This
  326. * is a fix for bug 4367783.
  327. */
  328. protected void writeCharArray(org.omg.CORBA_2_3.portable.OutputStream out,
  329. char[] array,
  330. int offset,
  331. int length)
  332. {
  333. out.write_wchar_array(array, offset, length);
  334. }
  335. private void write_Array(org.omg.CORBA_2_3.portable.OutputStream out, java.io.Serializable obj, Class type) {
  336. int i, length;
  337. if (type.isPrimitive()) {
  338. if (type == Integer.TYPE) {
  339. int[] array = (int[])((Object)obj);
  340. length = array.length;
  341. out.write_ulong(length);
  342. out.write_long_array(array, 0, length);
  343. } else if (type == Byte.TYPE) {
  344. byte[] array = (byte[])((Object)obj);
  345. length = array.length;
  346. out.write_ulong(length);
  347. out.write_octet_array(array, 0, length);
  348. } else if (type == Long.TYPE) {
  349. long[] array = (long[])((Object)obj);
  350. length = array.length;
  351. out.write_ulong(length);
  352. out.write_longlong_array(array, 0, length);
  353. } else if (type == Float.TYPE) {
  354. float[] array = (float[])((Object)obj);
  355. length = array.length;
  356. out.write_ulong(length);
  357. out.write_float_array(array, 0, length);
  358. } else if (type == Double.TYPE) {
  359. double[] array = (double[])((Object)obj);
  360. length = array.length;
  361. out.write_ulong(length);
  362. out.write_double_array(array, 0, length);
  363. } else if (type == Short.TYPE) {
  364. short[] array = (short[])((Object)obj);
  365. length = array.length;
  366. out.write_ulong(length);
  367. out.write_short_array(array, 0, length);
  368. } else if (type == Character.TYPE) {
  369. char[] array = (char[])((Object)obj);
  370. length = array.length;
  371. out.write_ulong(length);
  372. writeCharArray(out, array, 0, length);
  373. } else if (type == Boolean.TYPE) {
  374. boolean[] array = (boolean[])((Object)obj);
  375. length = array.length;
  376. out.write_ulong(length);
  377. out.write_boolean_array(array, 0, length);
  378. } else {
  379. throw new Error("Invalid primitive type : " + obj.getClass().getName());
  380. }
  381. } else if (type == java.lang.Object.class) {
  382. Object[] array = (Object[])((Object)obj);
  383. length = array.length;
  384. out.write_ulong(length);
  385. for (i = 0; i < length; i++) {
  386. Util.writeAny(out, array[i]);
  387. }
  388. } else {
  389. Object[] array = (Object[])((Object)obj);
  390. length = array.length;
  391. out.write_ulong(length);
  392. int callType = kValueType;
  393. if (type.isInterface()) {
  394. String className = type.getName();
  395. if (java.rmi.Remote.class.isAssignableFrom(type)) {
  396. // RMI Object reference...
  397. callType = kRemoteType;
  398. } else if (org.omg.CORBA.Object.class.isAssignableFrom(type)){
  399. // IDL Object reference...
  400. callType = kRemoteType;
  401. } else if (RepositoryId.isAbstractBase(type)) {
  402. // IDL Abstract Object reference...
  403. callType = kAbstractType;
  404. } else if (ObjectStreamClassCorbaExt.isAbstractInterface(type)) {
  405. callType = kAbstractType;
  406. }
  407. }
  408. for (i = 0; i < length; i++) {
  409. switch (callType) {
  410. case kRemoteType:
  411. Util.writeRemoteObject(out, array[i]);
  412. break;
  413. case kAbstractType:
  414. Util.writeAbstractObject(out,array[i]);
  415. break;
  416. case kValueType:
  417. try{
  418. out.write_value((java.io.Serializable)array[i]);
  419. }
  420. catch(ClassCastException cce){
  421. if (array[i] instanceof java.io.Serializable)
  422. throw cce;
  423. else {
  424. Utility.throwNotSerializableForCorba(array[i].getClass().getName());
  425. }
  426. }
  427. break;
  428. }
  429. }
  430. }
  431. }
  432. /**
  433. * Encapsulates reading of Java char arrays so that the 1.3 subclass
  434. * can override it without exposing internals across packages. This
  435. * is a fix for bug 4367783.
  436. */
  437. protected void readCharArray(org.omg.CORBA_2_3.portable.InputStream in,
  438. char[] array,
  439. int offset,
  440. int length)
  441. {
  442. in.read_wchar_array(array, offset, length);
  443. }
  444. private java.lang.Object read_Array(IIOPInputStream bridge,
  445. org.omg.CORBA_2_3.portable.InputStream in,
  446. Class sequence,
  447. com.sun.org.omg.SendingContext.CodeBase sender,
  448. int offset) {
  449. try {
  450. // Read length of coming array
  451. int length = in.read_ulong();
  452. int i;
  453. Class type = null;
  454. if (sequence == null) {
  455. for (i = 0; i < length; i++)
  456. in.read_value();
  457. return null;
  458. }
  459. type = sequence.getComponentType();
  460. if (type.isPrimitive()) {
  461. if (type == Integer.TYPE) {
  462. int[] array = new int[length];
  463. in.read_long_array(array, 0, length);
  464. return ((java.io.Serializable)((Object)array));
  465. } else if (type == Byte.TYPE) {
  466. byte[] array = new byte[length];
  467. in.read_octet_array(array, 0, length);
  468. return ((java.io.Serializable)((Object)array));
  469. } else if (type == Long.TYPE) {
  470. long[] array = new long[length];
  471. in.read_longlong_array(array, 0, length);
  472. return ((java.io.Serializable)((Object)array));
  473. } else if (type == Float.TYPE) {
  474. float[] array = new float[length];
  475. in.read_float_array(array, 0, length);
  476. return ((java.io.Serializable)((Object)array));
  477. } else if (type == Double.TYPE) {
  478. double[] array = new double[length];
  479. in.read_double_array(array, 0, length);
  480. return ((java.io.Serializable)((Object)array));
  481. } else if (type == Short.TYPE) {
  482. short[] array = new short[length];
  483. in.read_short_array(array, 0, length);
  484. return ((java.io.Serializable)((Object)array));
  485. } else if (type == Character.TYPE) {
  486. char[] array = new char[length];
  487. readCharArray(in, array, 0, length);
  488. return ((java.io.Serializable)((Object)array));
  489. } else if (type == Boolean.TYPE) {
  490. boolean[] array = new boolean[length];
  491. in.read_boolean_array(array, 0, length);
  492. return ((java.io.Serializable)((Object)array));
  493. } else {
  494. throw new Error("Invalid primitive type : " + sequence.getName());
  495. }
  496. } else if (type == java.lang.Object.class) {
  497. Object[] array = (Object[])java.lang.reflect.Array.newInstance(type, length);
  498. // Store this object and its beginning position
  499. // since there might be indirections to it while
  500. // it's been unmarshalled.
  501. bridge.activeRecursionMgr.addObject(offset, array);
  502. for (i = 0; i < length; i++) {
  503. Object objectValue = null;
  504. try {
  505. objectValue = Util.readAny(in);
  506. }
  507. catch(IndirectionException cdrie) {
  508. try {
  509. // The CDR stream had never seen the given offset before,
  510. // so check the recursion manager (it will throw an
  511. // IOException if it doesn't have a reference, either).
  512. objectValue = bridge.activeRecursionMgr.getObject(cdrie.offset);
  513. } catch (IOException ie) {
  514. // Translate to a MARSHAL exception since
  515. // ValueHandlers aren't allowed to throw
  516. // IOExceptions
  517. throw new MARSHAL("Invalid indirection to offset "
  518. + cdrie.offset,
  519. MinorCodes.INVALID_INDIRECTION,
  520. CompletionStatus.COMPLETED_NO);
  521. }
  522. }
  523. array[i] = objectValue;
  524. }
  525. return ((java.io.Serializable)((Object)array));
  526. } else {
  527. Object[] array = (Object[])java.lang.reflect.Array.newInstance(type, length);
  528. // Store this object and its beginning position
  529. // since there might be indirections to it while
  530. // it's been unmarshalled.
  531. bridge.activeRecursionMgr.addObject(offset, array);
  532. // Decide what method call to make based on the type. If
  533. // it is a type for which we need to load a stub, convert
  534. // the type to the correct stub type.
  535. int callType = kValueType;
  536. boolean narrow = false;
  537. if (type.isInterface()) {
  538. boolean loadStubClass = false;
  539. // String className = type.getName();
  540. if (java.rmi.Remote.class.isAssignableFrom(type)) {
  541. // RMI Object reference...
  542. // className = Utility.stubName(className);
  543. callType = kRemoteType;
  544. // for better performance, load the stub class once
  545. // instead of for each element of the array
  546. loadStubClass = true;
  547. } else if (org.omg.CORBA.Object.class.isAssignableFrom(type)){
  548. // IDL Object reference...
  549. // className = Utility.idlStubName(className);
  550. callType = kRemoteType;
  551. loadStubClass = true;
  552. } else if (RepositoryId.isAbstractBase(type)) {
  553. // IDL Abstract Object reference...
  554. // className = Utility.idlStubName(className);
  555. callType = kAbstractType;
  556. loadStubClass = true;
  557. } else if (ObjectStreamClassCorbaExt.isAbstractInterface(type)) {
  558. // RMI Abstract Object reference...
  559. // type = null;
  560. callType = kAbstractType;
  561. }
  562. if (loadStubClass) {
  563. try {
  564. String codebase = Util.getCodebase(type);
  565. String repID = RepositoryId.createForAnyType(type);
  566. type = Utility.loadStubClass(repID, codebase, type); //d11638
  567. } catch (ClassNotFoundException e) {
  568. narrow = true;
  569. }
  570. } else {
  571. narrow = true;
  572. }
  573. }
  574. for (i = 0; i < length; i++) {
  575. try {
  576. switch (callType) {
  577. case kRemoteType:
  578. if (!narrow)
  579. array[i] = (Object)in.read_Object(type);
  580. else {
  581. array[i] = Utility.readObjectAndNarrow(in, type);
  582. }
  583. break;
  584. case kAbstractType:
  585. if (!narrow)
  586. array[i] = (Object)in.read_abstract_interface(type);
  587. else {
  588. array[i] = Utility.readAbstractAndNarrow(in, type);
  589. }
  590. break;
  591. case kValueType:
  592. array[i] = (Object)in.read_value(type);
  593. break;
  594. }
  595. }
  596. catch(IndirectionException cdrie) {
  597. // The CDR stream had never seen the given offset before,
  598. // so check the recursion manager (it will throw an
  599. // IOException if it doesn't have a reference, either).
  600. try {
  601. array[i] = bridge.activeRecursionMgr.getObject(cdrie.offset);
  602. } catch (IOException ioe) {
  603. // Translate to a MARSHAL exception since
  604. // ValueHandlers aren't allowed to throw
  605. // IOExceptions
  606. throw new MARSHAL("Invalid indirection to offset "
  607. + cdrie.offset,
  608. MinorCodes.INVALID_INDIRECTION,
  609. CompletionStatus.COMPLETED_NO);
  610. }
  611. }
  612. }
  613. return ((java.io.Serializable)((Object)array));
  614. }
  615. } finally {
  616. // We've completed deserializing this object. Any
  617. // future indirections will be handled correctly at the
  618. // CDR level. The ActiveRecursionManager only deals with
  619. // objects currently being deserialized.
  620. bridge.activeRecursionMgr.removeObject(offset);
  621. }
  622. }
  623. private boolean isArray(String repId){
  624. return RepositoryId.cache.getId(repId).isSequence();
  625. }
  626. protected String getOutputStreamClassName() {
  627. return "com.sun.corba.se.internal.io.IIOPOutputStream";
  628. }
  629. private com.sun.corba.se.internal.io.IIOPOutputStream createOutputStream() {
  630. return (com.sun.corba.se.internal.io.IIOPOutputStream)AccessController.doPrivileged(new StreamFactory(getOutputStreamClassName()));
  631. }
  632. protected String getInputStreamClassName() {
  633. return "com.sun.corba.se.internal.io.IIOPInputStream";
  634. }
  635. private com.sun.corba.se.internal.io.IIOPInputStream createInputStream() {
  636. return (com.sun.corba.se.internal.io.IIOPInputStream)AccessController.doPrivileged(new StreamFactory(getInputStreamClassName()));
  637. }
  638. /**
  639. * Instantiates a class of the given name using the system ClassLoader
  640. * as part of a PrivilegedAction.
  641. *
  642. * It's private final so hopefully people can't grab it outside of
  643. * this class.
  644. *
  645. * If you're worried that someone could subclass ValueHandlerImpl,
  646. * install his own streams, and snoop what's on the wire:
  647. * Someone can do that only if he's allowed to use the feature
  648. * of installing his own javax.rmi.CORBA.Util delegate (via a
  649. * JVM property or orb.properties file, read the first time the
  650. * Util class is used). If he can do that, he can snoop
  651. * anything on the wire, anyway, without abusing the
  652. * StreamFactory class.
  653. */
  654. private static final class StreamFactory implements PrivilegedAction {
  655. private String className;
  656. public StreamFactory (String _className) {
  657. className = _className;
  658. }
  659. public Object run() {
  660. try {
  661. // Note: We must use the system ClassLoader here
  662. // since we want to load classes outside of the
  663. // core JDK when running J2EE Pure ORB and
  664. // talking to Kestrel.
  665. ClassLoader cl = Thread.currentThread().getContextClassLoader();
  666. if (cl == null)
  667. cl = ClassLoader.getSystemClassLoader();
  668. Class streamClass = cl.loadClass(className);
  669. // Since the ClassLoader should cache the class, this isn't
  670. // as expensive as it looks.
  671. return streamClass.newInstance();
  672. } catch(Throwable t) {
  673. throw new InternalError("Error loading "
  674. + className
  675. + ": "
  676. + t.getClass().getName()
  677. + ": "
  678. + t.getMessage());
  679. }
  680. }
  681. }
  682. /**
  683. * Our JDK 1.3 and JDK 1.3.1 behavior subclasses override this.
  684. * The correct behavior is for a Java char to map to a CORBA wchar,
  685. * but our older code mapped it to a CORBA char.
  686. */
  687. protected TCKind getJavaCharTCKind() {
  688. return TCKind.tk_wchar;
  689. }
  690. }