1. /*
  2. * @(#)Utility.java 1.41 04/06/21
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. /*
  8. * Licensed Materials - Property of IBM
  9. * RMI-IIOP v1.0
  10. * Copyright IBM Corp. 1998 1999 All Rights Reserved
  11. *
  12. * US Government Users Restricted Rights - Use, duplication or
  13. * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  14. */
  15. package com.sun.corba.se.impl.util;
  16. import org.omg.CORBA.SystemException;
  17. import org.omg.CORBA.CompletionStatus;
  18. import org.omg.CORBA.BAD_OPERATION;
  19. import org.omg.CORBA.BAD_INV_ORDER;
  20. import org.omg.CORBA.BAD_PARAM;
  21. import org.omg.CORBA.ORB;
  22. import org.omg.CORBA.Any;
  23. import org.omg.CORBA.TypeCode;
  24. import org.omg.CORBA.Principal;
  25. import org.omg.CORBA.portable.InputStream;
  26. import org.omg.CORBA.portable.OutputStream;
  27. import org.omg.CORBA.portable.BoxedValueHelper;
  28. import org.omg.CORBA.portable.ValueFactory;
  29. import org.omg.CORBA.portable.Streamable;
  30. import org.omg.CORBA.portable.Delegate;
  31. import java.util.Hashtable;
  32. import java.util.NoSuchElementException;
  33. import java.rmi.Remote;
  34. import java.rmi.NoSuchObjectException;
  35. import java.rmi.RemoteException;
  36. import java.rmi.server.RemoteStub;
  37. import javax.rmi.PortableRemoteObject;
  38. import javax.rmi.CORBA.Stub;
  39. import javax.rmi.CORBA.Tie;
  40. import javax.rmi.CORBA.Util;
  41. import java.io.Serializable;
  42. import java.io.File;
  43. import java.io.FileInputStream;
  44. import org.omg.PortableServer.POA;
  45. import com.sun.org.omg.SendingContext.CodeBase;
  46. import com.sun.corba.se.spi.logging.CORBALogDomains ;
  47. import com.sun.corba.se.spi.presentation.rmi.PresentationManager;
  48. import com.sun.corba.se.spi.presentation.rmi.StubAdapter ;
  49. import com.sun.corba.se.impl.logging.UtilSystemException ;
  50. import com.sun.corba.se.impl.logging.OMGSystemException ;
  51. /**
  52. * Handy class full of static functions.
  53. */
  54. public final class Utility {
  55. public static final String STUB_PREFIX = "_";
  56. public static final String RMI_STUB_SUFFIX = "_Stub";
  57. public static final String DYNAMIC_STUB_SUFFIX = "_DynamicStub" ;
  58. public static final String IDL_STUB_SUFFIX = "Stub";
  59. public static final String TIE_SUFIX = "_Tie";
  60. private static IdentityHashtable tieCache = new IdentityHashtable();
  61. private static IdentityHashtable tieToStubCache = new IdentityHashtable();
  62. private static IdentityHashtable stubToTieCache = new IdentityHashtable();
  63. private static Object CACHE_MISS = new Object();
  64. private static UtilSystemException wrapper = UtilSystemException.get(
  65. CORBALogDomains.UTIL ) ;
  66. private static OMGSystemException omgWrapper = OMGSystemException.get(
  67. CORBALogDomains.UTIL ) ;
  68. /**
  69. * Ensure that stubs, ties, and implementation objects
  70. * are 'connected' to the runtime. Converts implementation
  71. * objects to a type suitable for sending on the wire.
  72. * @param obj the object to connect.
  73. * @param orb the ORB to connect to if obj is exported to IIOP.
  74. * @param convertToStub true if implementation types should be
  75. * converted to Stubs rather than just org.omg.CORBA.Object.
  76. * @return the connected object.
  77. * @exception NoSuchObjectException if obj is an implementation
  78. * which has not been exported.
  79. */
  80. public static Object autoConnect(Object obj, ORB orb, boolean convertToStub)
  81. {
  82. if (obj == null) {
  83. return obj;
  84. }
  85. if (StubAdapter.isStub(obj)) {
  86. try {
  87. StubAdapter.getDelegate(obj) ;
  88. } catch (BAD_OPERATION okay) {
  89. try {
  90. StubAdapter.connect( obj, orb ) ;
  91. } catch (RemoteException e) {
  92. // The stub could not be connected because it
  93. // has an invalid IOR...
  94. throw wrapper.objectNotConnected( e,
  95. obj.getClass().getName() ) ;
  96. }
  97. }
  98. return obj;
  99. }
  100. if (obj instanceof Remote) {
  101. Remote remoteObj = (Remote)obj;
  102. Tie theTie = Util.getTie(remoteObj);
  103. if (theTie != null) {
  104. try {
  105. theTie.orb();
  106. } catch (SystemException okay) {
  107. theTie.orb(orb);
  108. }
  109. if (convertToStub) {
  110. Object result = loadStub(theTie,null,null,true);
  111. if (result != null) {
  112. return result;
  113. } else {
  114. throw wrapper.couldNotLoadStub(obj.getClass().getName());
  115. }
  116. } else {
  117. return StubAdapter.activateTie( theTie );
  118. }
  119. } else {
  120. // This is an implementation object which has not been
  121. // exported to IIOP OR is a JRMP stub or implementation
  122. // object which cannot be marshalled into an ORB stream...
  123. throw wrapper.objectNotExported( obj.getClass().getName() ) ;
  124. }
  125. }
  126. // Didn't need to do anything, just return the input...
  127. return obj;
  128. }
  129. /*
  130. * Get a new instance of an RMI-IIOP Tie for the
  131. * given server object.
  132. */
  133. public static Tie loadTie(Remote obj) {
  134. Tie result = null;
  135. Class objClass = obj.getClass();
  136. // Have we tried to find this guy before?
  137. synchronized (tieCache) {
  138. Object it = tieCache.get(obj);
  139. if (it == null) {
  140. // No, so try it...
  141. try {
  142. // First try the classname...
  143. result = loadTie(objClass);
  144. // If we don't have a valid tie at this point,
  145. // walk up the parent chain until we either
  146. // load a tie or encounter PortableRemoteObject
  147. // or java.lang.Object...
  148. while (result == null &&
  149. (objClass = objClass.getSuperclass()) != null &&
  150. objClass != PortableRemoteObject.class &&
  151. objClass != Object.class) {
  152. result = loadTie(objClass);
  153. }
  154. } catch (Exception ex) {
  155. wrapper.loadTieFailed( ex, objClass.getName() ) ;
  156. }
  157. // Did we get it?
  158. if (result == null) {
  159. // Nope, so cache that fact...
  160. tieCache.put(obj,CACHE_MISS);
  161. } else {
  162. // Yes, so cache it...
  163. tieCache.put(obj,result);
  164. }
  165. } else {
  166. // Yes, return a new instance or fail again if
  167. // it was a miss last time...
  168. if (it != CACHE_MISS) {
  169. try {
  170. result = (Tie) it.getClass().newInstance();
  171. } catch (Exception e) {
  172. }
  173. }
  174. }
  175. }
  176. return result;
  177. }
  178. /*
  179. * Load an RMI-IIOP Tie
  180. */
  181. private static Tie loadTie(Class theClass)
  182. {
  183. return com.sun.corba.se.spi.orb.ORB.getStubFactoryFactory().
  184. getTie( theClass ) ;
  185. }
  186. /*
  187. * Clear the stub/tie caches. Intended for use by
  188. * test code.
  189. */
  190. public static void clearCaches() {
  191. synchronized (tieToStubCache) {
  192. tieToStubCache.clear();
  193. }
  194. synchronized (tieCache) {
  195. tieCache.clear();
  196. }
  197. synchronized (stubToTieCache) {
  198. stubToTieCache.clear();
  199. }
  200. }
  201. /*
  202. * Load a class and check that it is assignable to a given type.
  203. * @param className the class name.
  204. * @param remoteCodebase the codebase to use. May be null.
  205. * @param loader the class loader of last resort. May be null.
  206. * @param expectedType the expected type. May be null.
  207. * @return the loaded class.
  208. */
  209. static Class loadClassOfType(String className, String remoteCodebase,
  210. ClassLoader loader, Class expectedType,
  211. ClassLoader expectedTypeClassLoader) throws ClassNotFoundException
  212. {
  213. Class loadedClass = null;
  214. try {
  215. //Sequence finding of the stubs according to spec
  216. try{
  217. //If-else is put here for speed up of J2EE.
  218. //According to the OMG spec, the if clause is not dead code.
  219. //It can occur if some compiler has allowed generation
  220. //into org.omg.stub hierarchy for non-offending
  221. //classes. This will encourage people to
  222. //produce non-offending class stubs in their own hierarchy.
  223. if (!PackagePrefixChecker.hasOffendingPrefix(
  224. PackagePrefixChecker.withoutPackagePrefix(className))){
  225. loadedClass = Util.loadClass(
  226. PackagePrefixChecker.withoutPackagePrefix(className),
  227. remoteCodebase,
  228. loader);
  229. } else {
  230. loadedClass = Util.loadClass(className, remoteCodebase,
  231. loader);
  232. }
  233. } catch (ClassNotFoundException cnfe) {
  234. loadedClass = Util.loadClass(className, remoteCodebase,
  235. loader);
  236. }
  237. if (expectedType == null)
  238. return loadedClass;
  239. } catch (ClassNotFoundException cnfe) {
  240. if (expectedType == null)
  241. throw cnfe;
  242. }
  243. // If no class was loaded, or if the loaded class is not of the
  244. // correct type, make a further attempt to load the correct class
  245. // using the classloader of the expected type.
  246. // _REVISIT_ Is this step necessary, or should the Util,loadClass
  247. // algorithm always produce a valid class if the setup is correct?
  248. // Does the OMG standard algorithm need to be changed to include
  249. // this step?
  250. if (loadedClass == null || !expectedType.isAssignableFrom(loadedClass)){
  251. if (expectedType.getClassLoader() != expectedTypeClassLoader)
  252. throw new IllegalArgumentException(
  253. "expectedTypeClassLoader not class loader of " +
  254. "expected Type.");
  255. if (expectedTypeClassLoader != null)
  256. loadedClass = expectedTypeClassLoader.loadClass(className);
  257. else {
  258. ClassLoader cl = Thread.currentThread().getContextClassLoader();
  259. if (cl == null)
  260. cl = ClassLoader.getSystemClassLoader();
  261. loadedClass = cl.loadClass(className);
  262. }
  263. }
  264. return loadedClass;
  265. }
  266. /*
  267. * Load a class and check that it is compatible with a given type.
  268. * @param className the class name.
  269. * @param remoteCodebase the codebase to use. May be null.
  270. * @param loadingContext the loading context. May be null.
  271. * @param relatedType the related type. May be null.
  272. * @return the loaded class.
  273. */
  274. public static Class loadClassForClass (String className,
  275. String remoteCodebase,
  276. ClassLoader loader,
  277. Class relatedType,
  278. ClassLoader relatedTypeClassLoader)
  279. throws ClassNotFoundException
  280. {
  281. if (relatedType == null)
  282. return Util.loadClass(className, remoteCodebase, loader);
  283. Class loadedClass = null;
  284. try {
  285. loadedClass = Util.loadClass(className, remoteCodebase, loader);
  286. } catch (ClassNotFoundException cnfe) {
  287. if (relatedType.getClassLoader() == null)
  288. throw cnfe;
  289. }
  290. // If no class was not loaded, or if the loaded class is not of the
  291. // correct type, make a further attempt to load the correct class
  292. // using the classloader of the related type.
  293. // _REVISIT_ Is this step necessary, or should the Util,loadClass
  294. // algorithm always produce a valid class if the setup is correct?
  295. // Does the OMG standard algorithm need to be changed to include
  296. // this step?
  297. if (loadedClass == null ||
  298. (loadedClass.getClassLoader() != null &&
  299. loadedClass.getClassLoader().loadClass(relatedType.getName()) !=
  300. relatedType))
  301. {
  302. if (relatedType.getClassLoader() != relatedTypeClassLoader)
  303. throw new IllegalArgumentException(
  304. "relatedTypeClassLoader not class loader of relatedType.");
  305. if (relatedTypeClassLoader != null)
  306. loadedClass = relatedTypeClassLoader.loadClass(className);
  307. }
  308. return loadedClass;
  309. }
  310. /**
  311. * Get the helper for an IDLValue
  312. *
  313. * Throws MARSHAL exception if no helper found.
  314. */
  315. public static BoxedValueHelper getHelper(Class clazz, String codebase,
  316. String repId)
  317. {
  318. String className = null;
  319. if (clazz != null) {
  320. className = clazz.getName();
  321. if (codebase == null)
  322. codebase = Util.getCodebase(clazz);
  323. } else {
  324. if (repId != null)
  325. className = RepositoryId.cache.getId(repId).getClassName();
  326. if (className == null) // no repId or unrecognized repId
  327. throw wrapper.unableLocateValueHelper(
  328. CompletionStatus.COMPLETED_MAYBE);
  329. }
  330. try {
  331. ClassLoader clazzLoader =
  332. (clazz == null ? null : clazz.getClassLoader());
  333. Class helperClass =
  334. loadClassForClass(className+"Helper", codebase, clazzLoader,
  335. clazz, clazzLoader);
  336. return (BoxedValueHelper)helperClass.newInstance();
  337. } catch (ClassNotFoundException cnfe) {
  338. throw wrapper.unableLocateValueHelper( CompletionStatus.COMPLETED_MAYBE,
  339. cnfe );
  340. } catch (IllegalAccessException iae) {
  341. throw wrapper.unableLocateValueHelper( CompletionStatus.COMPLETED_MAYBE,
  342. iae );
  343. } catch (InstantiationException ie) {
  344. throw wrapper.unableLocateValueHelper( CompletionStatus.COMPLETED_MAYBE,
  345. ie );
  346. } catch (ClassCastException cce) {
  347. throw wrapper.unableLocateValueHelper( CompletionStatus.COMPLETED_MAYBE,
  348. cce );
  349. }
  350. }
  351. /**
  352. * Get the factory for an IDLValue
  353. *
  354. * Throws MARSHAL exception if no factory found.
  355. */
  356. public static ValueFactory getFactory(Class clazz, String codebase,
  357. ORB orb, String repId)
  358. {
  359. ValueFactory factory = null;
  360. if ((orb != null) && (repId != null)) {
  361. try {
  362. factory = ((org.omg.CORBA_2_3.ORB)orb).lookup_value_factory(
  363. repId);
  364. } catch (org.omg.CORBA.BAD_PARAM ex) {
  365. // Try other way
  366. }
  367. }
  368. String className = null;
  369. if (clazz != null) {
  370. className = clazz.getName();
  371. if (codebase == null)
  372. codebase = Util.getCodebase(clazz);
  373. } else {
  374. if (repId != null)
  375. className = RepositoryId.cache.getId(repId).getClassName();
  376. if (className == null) // no repId or unrecognized repId
  377. throw omgWrapper.unableLocateValueFactory(
  378. CompletionStatus.COMPLETED_MAYBE);
  379. }
  380. // if earlier search found a non-default factory, or the same default
  381. // factory that loadClassForClass would return, bale out now...
  382. if (factory != null &&
  383. (!factory.getClass().getName().equals(className+"DefaultFactory") ||
  384. (clazz == null && codebase == null)))
  385. return factory;
  386. try {
  387. ClassLoader clazzLoader =
  388. (clazz == null ? null : clazz.getClassLoader());
  389. Class factoryClass =
  390. loadClassForClass(className+"DefaultFactory", codebase,
  391. clazzLoader, clazz, clazzLoader);
  392. return (ValueFactory)factoryClass.newInstance();
  393. } catch (ClassNotFoundException cnfe) {
  394. throw omgWrapper.unableLocateValueFactory(
  395. CompletionStatus.COMPLETED_MAYBE, cnfe);
  396. } catch (IllegalAccessException iae) {
  397. throw omgWrapper.unableLocateValueFactory(
  398. CompletionStatus.COMPLETED_MAYBE, iae);
  399. } catch (InstantiationException ie) {
  400. throw omgWrapper.unableLocateValueFactory(
  401. CompletionStatus.COMPLETED_MAYBE, ie);
  402. } catch (ClassCastException cce) {
  403. throw omgWrapper.unableLocateValueFactory(
  404. CompletionStatus.COMPLETED_MAYBE, cce);
  405. }
  406. }
  407. /*
  408. * Load an RMI-IIOP Stub given a Tie.
  409. * @param tie the tie.
  410. * @param stubClass the stub class. May be null.
  411. * @param remoteCodebase the codebase to use. May be null.
  412. * @param onlyMostDerived if true, will fail if cannot load a stub for the
  413. * first repID in the tie. If false, will walk all repIDs.
  414. * @return the stub or null if not found.
  415. */
  416. public static Remote loadStub(Tie tie,
  417. PresentationManager.StubFactory stubFactory,
  418. String remoteCodebase,
  419. boolean onlyMostDerived)
  420. {
  421. StubEntry entry = null;
  422. // Do we already have it cached?
  423. synchronized (tieToStubCache) {
  424. Object cached = tieToStubCache.get(tie);
  425. if (cached == null) {
  426. // No, so go try to load it...
  427. entry = loadStubAndUpdateCache(
  428. tie, stubFactory, remoteCodebase, onlyMostDerived);
  429. } else {
  430. // Yes, is it a stub? If not, it was a miss last
  431. // time, so return null again...
  432. if (cached != CACHE_MISS) {
  433. // It's a stub.
  434. entry = (StubEntry) cached;
  435. // Does the cached stub meet the requirements
  436. // of the caller? If the caller does not require
  437. // the most derived stub and does not require
  438. // a specific stub type, we don't have to check
  439. // any further because the cached type is good
  440. // enough...
  441. if (!entry.mostDerived && onlyMostDerived) {
  442. // We must reload because we do not have
  443. // the most derived cached already...
  444. // The stubFactory arg must be null here
  445. // to force onlyMostDerived=true to work
  446. // correctly.
  447. entry = loadStubAndUpdateCache(tie,null,
  448. remoteCodebase,true);
  449. } else if (stubFactory != null &&
  450. !StubAdapter.getTypeIds(entry.stub)[0].equals(
  451. stubFactory.getTypeIds()[0]) )
  452. {
  453. // We do not have exactly the right stub. First, try to
  454. // upgrade the cached stub by forcing it to the most
  455. // derived stub...
  456. entry = loadStubAndUpdateCache(tie,null,
  457. remoteCodebase,true);
  458. // If that failed, try again with the exact type
  459. // we need...
  460. if (entry == null) {
  461. entry = loadStubAndUpdateCache(tie,stubFactory,
  462. remoteCodebase,onlyMostDerived);
  463. }
  464. } else {
  465. // Use the cached stub. Is the delegate set?
  466. try {
  467. Delegate stubDel = StubAdapter.getDelegate(
  468. entry.stub ) ;
  469. } catch (Exception e2) {
  470. // No, so set it if we can...
  471. try {
  472. Delegate del = StubAdapter.getDelegate(
  473. tie ) ;
  474. StubAdapter.setDelegate( entry.stub,
  475. del ) ;
  476. } catch (Exception e) {}
  477. }
  478. }
  479. }
  480. }
  481. }
  482. if (entry != null) {
  483. return (Remote)entry.stub;
  484. } else {
  485. return null;
  486. }
  487. }
  488. /*
  489. * Load an RMI-IIOP Stub given a Tie, but do not look in the cache.
  490. * This method must be called with the lock held for tieToStubCache.
  491. * @param tie the tie.
  492. * @param stubFactory the stub factory. May be null.
  493. * @param remoteCodebase the codebase to use. May be null.
  494. * @param onlyMostDerived if true, will fail if cannot load a stub for the
  495. * first repID in the tie. If false, will walk all repIDs.
  496. * @return the StubEntry or null if not found.
  497. */
  498. private static StubEntry loadStubAndUpdateCache (
  499. Tie tie, PresentationManager.StubFactory stubFactory,
  500. String remoteCodebase, boolean onlyMostDerived)
  501. {
  502. org.omg.CORBA.Object stub = null;
  503. StubEntry entry = null;
  504. boolean tieIsStub = StubAdapter.isStub( tie ) ;
  505. if (stubFactory != null) {
  506. try {
  507. stub = stubFactory.makeStub();
  508. } catch (Throwable e) {
  509. wrapper.stubFactoryCouldNotMakeStub( e ) ;
  510. if (e instanceof ThreadDeath) {
  511. throw (ThreadDeath) e;
  512. }
  513. }
  514. } else {
  515. String[] ids = null;
  516. if (tieIsStub) {
  517. ids = StubAdapter.getTypeIds( tie ) ;
  518. } else {
  519. // This will throw an exception if the tie
  520. // is not a Servant. XXX Handle this better?
  521. ids = ((org.omg.PortableServer.Servant)tie).
  522. _all_interfaces( null, null );
  523. }
  524. if (remoteCodebase == null) {
  525. remoteCodebase = Util.getCodebase(tie.getClass());
  526. }
  527. if (ids.length == 0) {
  528. stub = new org.omg.stub.java.rmi._Remote_Stub();
  529. } else {
  530. // Now walk all the RepIDs till we find a stub or fail...
  531. for (int i = 0; i < ids.length; i++) {
  532. if (ids[i].length() == 0) {
  533. stub = new org.omg.stub.java.rmi._Remote_Stub();
  534. break;
  535. }
  536. try {
  537. PresentationManager.StubFactoryFactory stubFactoryFactory =
  538. com.sun.corba.se.spi.orb.ORB.getStubFactoryFactory();
  539. RepositoryId rid = RepositoryId.cache.getId( ids[i] ) ;
  540. String className = rid.getClassName() ;
  541. boolean isIDLInterface = rid.isIDLType() ;
  542. stubFactory = stubFactoryFactory.createStubFactory(
  543. className, isIDLInterface, remoteCodebase, null,
  544. tie.getClass().getClassLoader() ) ;
  545. stub = stubFactory.makeStub();
  546. break;
  547. } catch (Exception e) {
  548. wrapper.errorInMakeStubFromRepositoryId( e ) ;
  549. }
  550. if (onlyMostDerived)
  551. break;
  552. }
  553. }
  554. }
  555. if (stub == null) {
  556. // Stub == null, so cache the miss...
  557. tieToStubCache.put(tie,CACHE_MISS);
  558. } else {
  559. if (tieIsStub) {
  560. try {
  561. Delegate del = StubAdapter.getDelegate( tie ) ;
  562. StubAdapter.setDelegate( stub, del ) ;
  563. } catch( Exception e1 ) {
  564. // The tie does not have a delegate set, so stash
  565. // this tie away using the stub as a key so that
  566. // later, when the stub is connected, we can find
  567. // and connect the tie as well...
  568. synchronized (stubToTieCache) {
  569. stubToTieCache.put(stub,tie);
  570. }
  571. }
  572. } else {
  573. // Tie extends Servant
  574. try {
  575. Delegate delegate = StubAdapter.getDelegate( tie ) ;
  576. StubAdapter.setDelegate( stub, delegate ) ;
  577. } catch( org.omg.CORBA.BAD_INV_ORDER bad) {
  578. synchronized (stubToTieCache) {
  579. stubToTieCache.put(stub,tie);
  580. }
  581. } catch( Exception e ) {
  582. // Exception is caught because of any of the
  583. // following reasons
  584. // 1) POA is not associated with the TIE
  585. // 2) POA Policies for the tie-associated POA
  586. // does not support _this_object() call.
  587. throw wrapper.noPoa( e ) ;
  588. }
  589. }
  590. // Update the cache...
  591. entry = new StubEntry(stub,onlyMostDerived);
  592. tieToStubCache.put(tie,entry);
  593. }
  594. return entry;
  595. }
  596. /*
  597. * If we loadStub(Tie,...) stashed away a tie which was
  598. * not connected, remove it from the cache and return
  599. * it.
  600. */
  601. public static Tie getAndForgetTie (org.omg.CORBA.Object stub) {
  602. synchronized (stubToTieCache) {
  603. return (Tie) stubToTieCache.remove(stub);
  604. }
  605. }
  606. /*
  607. * Remove any cached Stub for the given tie.
  608. */
  609. public static void purgeStubForTie (Tie tie) {
  610. StubEntry entry;
  611. synchronized (tieToStubCache) {
  612. entry = (StubEntry)tieToStubCache.remove(tie);
  613. }
  614. if (entry != null) {
  615. synchronized (stubToTieCache) {
  616. stubToTieCache.remove(entry.stub);
  617. }
  618. }
  619. }
  620. /*
  621. * Remove cached tie/servant pair.
  622. */
  623. public static void purgeTieAndServant (Tie tie) {
  624. synchronized (tieCache) {
  625. Object target = tie.getTarget();
  626. if (target != null)
  627. tieCache.remove(target);
  628. }
  629. }
  630. /*
  631. * Convert a RepId to a stubName...
  632. */
  633. public static String stubNameFromRepID (String repID) {
  634. // Convert the typeid to a RepositoryId instance, get
  635. // the className and mangle it as needed...
  636. RepositoryId id = RepositoryId.cache.getId(repID);
  637. String className = id.getClassName();
  638. if (id.isIDLType()) {
  639. className = idlStubName(className);
  640. } else {
  641. className = stubName(className);
  642. }
  643. return className;
  644. }
  645. /*
  646. * Load an RMI-IIOP Stub. This is used in PortableRemoteObject.narrow.
  647. */
  648. public static Remote loadStub (org.omg.CORBA.Object narrowFrom,
  649. Class narrowTo)
  650. {
  651. Remote result = null;
  652. try {
  653. // Get the codebase from the delegate to use when loading
  654. // the new stub, if possible...
  655. String codebase = null;
  656. try {
  657. // We can't assume that narrowFrom is a CORBA_2_3 stub, yet
  658. // it may have a 2_3 Delegate that provides a codebase. Swallow
  659. // the ClassCastException otherwise.
  660. Delegate delegate = StubAdapter.getDelegate( narrowFrom ) ;
  661. codebase = ((org.omg.CORBA_2_3.portable.Delegate)delegate).
  662. get_codebase(narrowFrom);
  663. } catch (ClassCastException e) {
  664. wrapper.classCastExceptionInLoadStub( e ) ;
  665. }
  666. PresentationManager.StubFactoryFactory sff =
  667. com.sun.corba.se.spi.orb.ORB.getStubFactoryFactory() ;
  668. PresentationManager.StubFactory sf = sff.createStubFactory(
  669. narrowTo.getName(), false, codebase, narrowTo,
  670. narrowTo.getClassLoader() ) ;
  671. result = (Remote)sf.makeStub() ;
  672. StubAdapter.setDelegate( result,
  673. StubAdapter.getDelegate( narrowFrom ) ) ;
  674. } catch (Exception err) {
  675. wrapper.exceptionInLoadStub( err ) ;
  676. }
  677. return result;
  678. }
  679. /*
  680. * Load an RMI-IIOP Stub class. This is used in the
  681. * StaticStubFactoryFactory code.
  682. */
  683. public static Class loadStubClass(String repID,
  684. String remoteCodebase,
  685. Class expectedType)
  686. throws ClassNotFoundException
  687. {
  688. // Get the repID and check for "" special case.
  689. // We should never be called with it (See CDRInputStream
  690. // and the loadStub() method)...
  691. if (repID.length() == 0) {
  692. throw new ClassNotFoundException();
  693. }
  694. // Get the stubname from the repID and load
  695. // the class. If we have a valid 'sender', fall
  696. // back to using its codebase if we need to...
  697. String className = Utility.stubNameFromRepID(repID);
  698. ClassLoader expectedTypeClassLoader = (expectedType == null ? null :
  699. expectedType.getClassLoader());
  700. try {
  701. return loadClassOfType(className,
  702. remoteCodebase,
  703. expectedTypeClassLoader,
  704. expectedType,
  705. expectedTypeClassLoader);
  706. } catch (ClassNotFoundException e) {
  707. return loadClassOfType(PackagePrefixChecker.packagePrefix() + className,
  708. remoteCodebase,
  709. expectedTypeClassLoader,
  710. expectedType,
  711. expectedTypeClassLoader);
  712. }
  713. }
  714. /**
  715. * Create an RMI stub name.
  716. */
  717. public static String stubName (String className)
  718. {
  719. return stubName( className, false ) ;
  720. }
  721. public static String dynamicStubName( String className )
  722. {
  723. return stubName( className, true ) ;
  724. }
  725. private static String stubName( String className,
  726. boolean isDynamic )
  727. {
  728. String name = stubNameForCompiler( className, isDynamic ) ;
  729. if (PackagePrefixChecker.hasOffendingPrefix( name ))
  730. name = PackagePrefixChecker.packagePrefix() + name ;
  731. return name ;
  732. }
  733. public static String stubNameForCompiler (String className)
  734. {
  735. return stubNameForCompiler( className, false ) ;
  736. }
  737. private static String stubNameForCompiler( String className,
  738. boolean isDynamic )
  739. {
  740. int index = className.indexOf('$');
  741. if (index < 0) {
  742. index = className.lastIndexOf('.');
  743. }
  744. String suffix = isDynamic ? DYNAMIC_STUB_SUFFIX :
  745. RMI_STUB_SUFFIX ;
  746. if (index > 0) {
  747. return className.substring(0,index+1) + STUB_PREFIX +
  748. className.substring(index+1) + suffix;
  749. } else {
  750. return STUB_PREFIX + className + suffix;
  751. }
  752. }
  753. /**
  754. * Create an RMI tie name.
  755. */
  756. public static String tieName (String className)
  757. {
  758. return
  759. PackagePrefixChecker.hasOffendingPrefix(tieNameForCompiler(className)) ?
  760. PackagePrefixChecker.packagePrefix() + tieNameForCompiler(className) :
  761. tieNameForCompiler(className);
  762. }
  763. public static String tieNameForCompiler (String className)
  764. {
  765. int index = className.indexOf('$');
  766. if (index < 0) {
  767. index = className.lastIndexOf('.');
  768. }
  769. if (index > 0) {
  770. return className.substring(0,index+1) +
  771. STUB_PREFIX +
  772. className.substring(index+1) +
  773. TIE_SUFIX;
  774. } else {
  775. return STUB_PREFIX +
  776. className +
  777. TIE_SUFIX;
  778. }
  779. }
  780. /**
  781. * Throws the CORBA equivalent of a java.io.NotSerializableException
  782. */
  783. public static void throwNotSerializableForCorba(String className) {
  784. throw omgWrapper.notSerializable( CompletionStatus.COMPLETED_MAYBE,
  785. className ) ;
  786. }
  787. /**
  788. * Create an IDL stub name.
  789. */
  790. public static String idlStubName(String className)
  791. {
  792. String result = null;
  793. int index = className.lastIndexOf('.');
  794. if (index > 0) {
  795. result = className.substring(0,index+1) +
  796. STUB_PREFIX +
  797. className.substring(index+1) +
  798. IDL_STUB_SUFFIX;
  799. } else {
  800. result = STUB_PREFIX +
  801. className +
  802. IDL_STUB_SUFFIX;
  803. }
  804. return result;
  805. }
  806. public static void printStackTrace()
  807. {
  808. Throwable thr = new Throwable( "Printing stack trace:" ) ;
  809. thr.fillInStackTrace() ;
  810. thr.printStackTrace() ;
  811. }
  812. /**
  813. * Read an object reference from the input stream and narrow
  814. * it to the desired type.
  815. * @param in the stream to read from.
  816. * @throws ClassCastException if narrowFrom cannot be cast to narrowTo.
  817. */
  818. public static Object readObjectAndNarrow(InputStream in,
  819. Class narrowTo)
  820. throws ClassCastException
  821. {
  822. Object result = in.read_Object();
  823. if (result != null)
  824. return PortableRemoteObject.narrow(result, narrowTo);
  825. else
  826. return null;
  827. }
  828. /**
  829. * Read an abstract interface type from the input stream and narrow
  830. * it to the desired type.
  831. * @param in the stream to read from.
  832. * @throws ClassCastException if narrowFrom cannot be cast to narrowTo.
  833. */
  834. public static Object readAbstractAndNarrow(
  835. org.omg.CORBA_2_3.portable.InputStream in, Class narrowTo)
  836. throws ClassCastException
  837. {
  838. Object result = in.read_abstract_interface();
  839. if (result != null)
  840. return PortableRemoteObject.narrow(result, narrowTo);
  841. else
  842. return null;
  843. }
  844. /** Converts an Ascii Character into Hexadecimal digit
  845. */
  846. static int hexOf( char x )
  847. {
  848. int val;
  849. val = x - '0';
  850. if (val >=0 && val <= 9)
  851. return val;
  852. val = (x - 'a') + 10;
  853. if (val >= 10 && val <= 15)
  854. return val;
  855. val = (x - 'A') + 10;
  856. if (val >= 10 && val <= 15)
  857. return val;
  858. throw wrapper.badHexDigit() ;
  859. }
  860. }
  861. class StubEntry {
  862. org.omg.CORBA.Object stub;
  863. boolean mostDerived;
  864. StubEntry(org.omg.CORBA.Object stub, boolean mostDerived) {
  865. this.stub = stub;
  866. this.mostDerived = mostDerived;
  867. }
  868. }