1. /*
  2. * @(#)InterceptorInvoker.java 1.32 03/12/19
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package com.sun.corba.se.impl.interceptors;
  8. import org.omg.CORBA.CompletionStatus;
  9. import org.omg.CORBA.INTERNAL;
  10. import org.omg.CORBA.SystemException;
  11. import org.omg.CORBA.portable.Delegate;
  12. import org.omg.PortableInterceptor.LOCATION_FORWARD;
  13. import org.omg.PortableInterceptor.SUCCESSFUL;
  14. import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;
  15. import org.omg.PortableInterceptor.TRANSPORT_RETRY;
  16. import org.omg.PortableInterceptor.USER_EXCEPTION;
  17. import org.omg.PortableInterceptor.ClientRequestInfo;
  18. import org.omg.PortableInterceptor.ClientRequestInterceptor;
  19. import org.omg.PortableInterceptor.ForwardRequest;
  20. import org.omg.PortableInterceptor.IORInterceptor;
  21. import org.omg.PortableInterceptor.IORInterceptor_3_0;
  22. import org.omg.PortableInterceptor.ServerRequestInfo;
  23. import org.omg.PortableInterceptor.ServerRequestInterceptor;
  24. import org.omg.PortableInterceptor.ObjectReferenceTemplate;
  25. import com.sun.corba.se.spi.ior.IOR;
  26. import com.sun.corba.se.spi.oa.ObjectAdapter;
  27. import com.sun.corba.se.spi.orb.ORB;
  28. import com.sun.corba.se.impl.orbutil.ORBUtility;
  29. /**
  30. * Handles invocation of interceptors. Has specific knowledge of how to
  31. * invoke IOR, ClientRequest, and ServerRequest interceptors.
  32. * Makes use of the InterceptorList to retrieve the list of interceptors to
  33. * be invoked. Most methods in this class are package scope so that they
  34. * may only be called from the PIHandlerImpl.
  35. */
  36. public class InterceptorInvoker {
  37. // The ORB
  38. private ORB orb;
  39. // The list of interceptors to be invoked
  40. private InterceptorList interceptorList;
  41. // True if interceptors are to be invoked, or false if not
  42. // Note: This is a global enable/disable flag, whereas the enable flag
  43. // in the RequestInfoStack in PIHandlerImpl is only for a particular Thread.
  44. private boolean enabled = false;
  45. // PICurrent variable.
  46. private PICurrent current;
  47. // NOTE: Be careful about adding additional attributes to this class.
  48. // Multiple threads may be calling methods on this invoker at the same
  49. // time.
  50. /**
  51. * Creates a new Interceptor Invoker. Constructor is package scope so
  52. * only the ORB can create it. The invoker is initially disabled, and
  53. * must be explicitly enabled using setEnabled().
  54. */
  55. InterceptorInvoker( ORB orb, InterceptorList interceptorList,
  56. PICurrent piCurrent )
  57. {
  58. this.orb = orb;
  59. this.interceptorList = interceptorList;
  60. this.enabled = false;
  61. this.current = piCurrent;
  62. }
  63. /**
  64. * Enables or disables the interceptor invoker
  65. */
  66. void setEnabled( boolean enabled ) {
  67. this.enabled = enabled;
  68. }
  69. /*
  70. **********************************************************************
  71. * IOR Interceptor invocation
  72. **********************************************************************/
  73. /**
  74. * Called when a new POA is created.
  75. *
  76. * @param oa The Object Adapter associated with the IOR interceptor.
  77. */
  78. void objectAdapterCreated( ObjectAdapter oa ) {
  79. // If invocation is not yet enabled, don't do anything.
  80. if( enabled ) {
  81. // Create IORInfo object to pass to IORInterceptors:
  82. IORInfoImpl info = new IORInfoImpl( oa );
  83. // Call each IORInterceptor:
  84. IORInterceptor[] iorInterceptors =
  85. (IORInterceptor[])interceptorList.getInterceptors(
  86. InterceptorList.INTERCEPTOR_TYPE_IOR );
  87. int size = iorInterceptors.length;
  88. // Implementation note:
  89. // This loop counts backwards for greater efficiency.
  90. // Benchmarks have shown that counting down is more efficient
  91. // than counting up in Java for loops, as a compare to zero is
  92. // faster than a subtract and compare to zero. In this case,
  93. // it doesn't really matter much, but it's simply a force of habit.
  94. for( int i = (size - 1); i >= 0; i-- ) {
  95. IORInterceptor interceptor = iorInterceptors[i];
  96. try {
  97. interceptor.establish_components( info );
  98. }
  99. catch( Exception e ) {
  100. // as per PI spec (orbos/99-12-02 sec 7.2.1), if
  101. // establish_components throws an exception, ignore it.
  102. }
  103. }
  104. // Change the state so that only template operations are valid
  105. info.makeStateEstablished() ;
  106. for( int i = (size - 1); i >= 0; i-- ) {
  107. IORInterceptor interceptor = iorInterceptors[i];
  108. if (interceptor instanceof IORInterceptor_3_0) {
  109. IORInterceptor_3_0 interceptor30 = (IORInterceptor_3_0)interceptor ;
  110. // Note that exceptions here are NOT ignored, as per the
  111. // ORT spec (orbos/01-01-04)
  112. interceptor30.components_established( info );
  113. }
  114. }
  115. // Change the state so that no operations are valid,
  116. // in case a reference to info escapes this scope.
  117. // This also completes the actions associated with the
  118. // template interceptors on this POA.
  119. info.makeStateDone() ;
  120. }
  121. }
  122. void adapterManagerStateChanged( int managerId, short newState )
  123. {
  124. if (enabled) {
  125. IORInterceptor[] interceptors =
  126. (IORInterceptor[])interceptorList.getInterceptors(
  127. InterceptorList.INTERCEPTOR_TYPE_IOR );
  128. int size = interceptors.length;
  129. for( int i = (size - 1); i >= 0; i-- ) {
  130. try {
  131. IORInterceptor interceptor = interceptors[i];
  132. if (interceptor instanceof IORInterceptor_3_0) {
  133. IORInterceptor_3_0 interceptor30 = (IORInterceptor_3_0)interceptor ;
  134. interceptor30.adapter_manager_state_changed( managerId,
  135. newState );
  136. }
  137. } catch (Exception exc) {
  138. // No-op: ignore exception in this case
  139. }
  140. }
  141. }
  142. }
  143. void adapterStateChanged( ObjectReferenceTemplate[] templates,
  144. short newState )
  145. {
  146. if (enabled) {
  147. IORInterceptor[] interceptors =
  148. (IORInterceptor[])interceptorList.getInterceptors(
  149. InterceptorList.INTERCEPTOR_TYPE_IOR );
  150. int size = interceptors.length;
  151. for( int i = (size - 1); i >= 0; i-- ) {
  152. try {
  153. IORInterceptor interceptor = interceptors[i];
  154. if (interceptor instanceof IORInterceptor_3_0) {
  155. IORInterceptor_3_0 interceptor30 = (IORInterceptor_3_0)interceptor ;
  156. interceptor30.adapter_state_changed( templates, newState );
  157. }
  158. } catch (Exception exc) {
  159. // No-op: ignore exception in this case
  160. }
  161. }
  162. }
  163. }
  164. /*
  165. **********************************************************************
  166. * Client Interceptor invocation
  167. **********************************************************************/
  168. /**
  169. * Invokes either send_request, or send_poll, depending on the value
  170. * of info.getStartingPointCall()
  171. */
  172. void invokeClientInterceptorStartingPoint( ClientRequestInfoImpl info ) {
  173. // If invocation is not yet enabled, don't do anything.
  174. if( enabled ) {
  175. try {
  176. // Make a a fresh slot table available to TSC in case
  177. // interceptors need to make out calls.
  178. // Client's TSC is now RSC via RequestInfo.
  179. current.pushSlotTable( );
  180. info.setPICurrentPushed( true );
  181. info.setCurrentExecutionPoint( info.EXECUTION_POINT_STARTING );
  182. // Get all ClientRequestInterceptors:
  183. ClientRequestInterceptor[] clientInterceptors =
  184. (ClientRequestInterceptor[])interceptorList.
  185. getInterceptors( InterceptorList.INTERCEPTOR_TYPE_CLIENT );
  186. int size = clientInterceptors.length;
  187. // We will assume that all interceptors returned successfully,
  188. // and adjust the flowStackIndex to the appropriate value if
  189. // we later discover otherwise.
  190. int flowStackIndex = size;
  191. boolean continueProcessing = true;
  192. // Determine whether we are calling send_request or send_poll:
  193. // (This is currently commented out because our ORB does not
  194. // yet support the Messaging specification, so send_poll will
  195. // never occur. Once we have implemented messaging, this may
  196. // be uncommented.)
  197. // int startingPointCall = info.getStartingPointCall();
  198. for( int i = 0; continueProcessing && (i < size); i++ ) {
  199. try {
  200. clientInterceptors[i].send_request( info );
  201. // Again, it is not necessary for a switch here, since
  202. // there is only one starting point call type (see
  203. // above comment).
  204. //switch( startingPointCall ) {
  205. //case ClientRequestInfoImpl.CALL_SEND_REQUEST:
  206. //clientInterceptors[i].send_request( info );
  207. //break;
  208. //case ClientRequestInfoImpl.CALL_SEND_POLL:
  209. //clientInterceptors[i].send_poll( info );
  210. //break;
  211. //}
  212. }
  213. catch( ForwardRequest e ) {
  214. // as per PI spec (orbos/99-12-02 sec 5.2.1.), if
  215. // interception point throws a ForwardRequest,
  216. // no other Interceptors' send_request operations are
  217. // called.
  218. flowStackIndex = i;
  219. info.setForwardRequest( e );
  220. info.setEndingPointCall(
  221. ClientRequestInfoImpl.CALL_RECEIVE_OTHER );
  222. info.setReplyStatus( LOCATION_FORWARD.value );
  223. updateClientRequestDispatcherForward( info );
  224. // For some reason, using break here causes the VM on
  225. // NT to lose track of the value of flowStackIndex
  226. // after exiting the for loop. I changed this to
  227. // check a boolean value instead and it seems to work
  228. // fine.
  229. continueProcessing = false;
  230. }
  231. catch( SystemException e ) {
  232. // as per PI spec (orbos/99-12-02 sec 5.2.1.), if
  233. // interception point throws a SystemException,
  234. // no other Interceptors' send_request operations are
  235. // called.
  236. flowStackIndex = i;
  237. info.setEndingPointCall(
  238. ClientRequestInfoImpl.CALL_RECEIVE_EXCEPTION );
  239. info.setReplyStatus( SYSTEM_EXCEPTION.value );
  240. info.setException( e );
  241. // For some reason, using break here causes the VM on
  242. // NT to lose track of the value of flowStackIndex
  243. // after exiting the for loop. I changed this to
  244. // check a boolean value instead and it seems to
  245. // work fine.
  246. continueProcessing = false;
  247. }
  248. }
  249. // Remember where we left off in the flow stack:
  250. info.setFlowStackIndex( flowStackIndex );
  251. }
  252. finally {
  253. // Make the SlotTable fresh for the next interception point.
  254. current.resetSlotTable( );
  255. }
  256. } // end enabled check
  257. }
  258. /**
  259. * Invokes either receive_reply, receive_exception, or receive_other,
  260. * depending on the value of info.getEndingPointCall()
  261. */
  262. void invokeClientInterceptorEndingPoint( ClientRequestInfoImpl info ) {
  263. // If invocation is not yet enabled, don't do anything.
  264. if( enabled ) {
  265. try {
  266. // NOTE: It is assumed someplace else prepared a
  267. // fresh TSC slot table.
  268. info.setCurrentExecutionPoint( info.EXECUTION_POINT_ENDING );
  269. // Get all ClientRequestInterceptors:
  270. ClientRequestInterceptor[] clientInterceptors =
  271. (ClientRequestInterceptor[])interceptorList.
  272. getInterceptors( InterceptorList.INTERCEPTOR_TYPE_CLIENT );
  273. int flowStackIndex = info.getFlowStackIndex();
  274. // Determine whether we are calling receive_reply,
  275. // receive_exception, or receive_other:
  276. int endingPointCall = info.getEndingPointCall();
  277. // If we would be calling RECEIVE_REPLY, but this is a
  278. // one-way call, override this and call receive_other:
  279. if( ( endingPointCall ==
  280. ClientRequestInfoImpl.CALL_RECEIVE_REPLY ) &&
  281. info.getIsOneWay() )
  282. {
  283. endingPointCall = ClientRequestInfoImpl.CALL_RECEIVE_OTHER;
  284. info.setEndingPointCall( endingPointCall );
  285. }
  286. // Only step through the interceptors whose starting points
  287. // have successfully returned.
  288. // Unlike the previous loop, this one counts backwards for a
  289. // reason - we must execute these in the reverse order of the
  290. // starting points.
  291. for( int i = (flowStackIndex - 1); i >= 0; i-- ) {
  292. try {
  293. switch( endingPointCall ) {
  294. case ClientRequestInfoImpl.CALL_RECEIVE_REPLY:
  295. clientInterceptors[i].receive_reply( info );
  296. break;
  297. case ClientRequestInfoImpl.CALL_RECEIVE_EXCEPTION:
  298. clientInterceptors[i].receive_exception( info );
  299. break;
  300. case ClientRequestInfoImpl.CALL_RECEIVE_OTHER:
  301. clientInterceptors[i].receive_other( info );
  302. break;
  303. }
  304. }
  305. catch( ForwardRequest e ) {
  306. // as per PI spec (orbos/99-12-02 sec 5.2.1.), if
  307. // interception point throws a ForwardException,
  308. // ending point call changes to receive_other.
  309. endingPointCall =
  310. ClientRequestInfoImpl.CALL_RECEIVE_OTHER;
  311. info.setEndingPointCall( endingPointCall );
  312. info.setReplyStatus( LOCATION_FORWARD.value );
  313. info.setForwardRequest( e );
  314. updateClientRequestDispatcherForward( info );
  315. }
  316. catch( SystemException e ) {
  317. // as per PI spec (orbos/99-12-02 sec 5.2.1.), if
  318. // interception point throws a SystemException,
  319. // ending point call changes to receive_exception.
  320. endingPointCall =
  321. ClientRequestInfoImpl.CALL_RECEIVE_EXCEPTION;
  322. info.setEndingPointCall( endingPointCall );
  323. info.setReplyStatus( SYSTEM_EXCEPTION.value );
  324. info.setException( e );
  325. }
  326. }
  327. }
  328. finally {
  329. // See doc for setPICurrentPushed as to why this is necessary.
  330. // Check info for null in case errors happen before initiate.
  331. if (info != null && info.isPICurrentPushed()) {
  332. current.popSlotTable( );
  333. // After the pop, original client's TSC slot table
  334. // remains avaiable via PICurrent.
  335. }
  336. }
  337. } // end enabled check
  338. }
  339. /*
  340. **********************************************************************
  341. * Server Interceptor invocation
  342. **********************************************************************/
  343. /**
  344. * Invokes receive_request_service_context interception points.
  345. */
  346. void invokeServerInterceptorStartingPoint( ServerRequestInfoImpl info ) {
  347. // If invocation is not yet enabled, don't do anything.
  348. if( enabled ) {
  349. try {
  350. // Make a fresh slot table for RSC.
  351. current.pushSlotTable();
  352. info.setSlotTable(current.getSlotTable());
  353. // Make a fresh slot table for TSC in case
  354. // interceptors need to make out calls.
  355. current.pushSlotTable( );
  356. info.setCurrentExecutionPoint( info.EXECUTION_POINT_STARTING );
  357. // Get all ServerRequestInterceptors:
  358. ServerRequestInterceptor[] serverInterceptors =
  359. (ServerRequestInterceptor[])interceptorList.
  360. getInterceptors( InterceptorList.INTERCEPTOR_TYPE_SERVER );
  361. int size = serverInterceptors.length;
  362. // We will assume that all interceptors returned successfully,
  363. // and adjust the flowStackIndex to the appropriate value if
  364. // we later discover otherwise.
  365. int flowStackIndex = size;
  366. boolean continueProcessing = true;
  367. // Currently, there is only one server-side starting point
  368. // interceptor called receive_request_service_contexts.
  369. for( int i = 0; continueProcessing && (i < size); i++ ) {
  370. try {
  371. serverInterceptors[i].
  372. receive_request_service_contexts( info );
  373. }
  374. catch( ForwardRequest e ) {
  375. // as per PI spec (orbos/99-12-02 sec 5.3.1.), if
  376. // interception point throws a ForwardRequest,
  377. // no other Interceptors' starting points are
  378. // called and send_other is called.
  379. flowStackIndex = i;
  380. info.setForwardRequest( e );
  381. info.setIntermediatePointCall(
  382. ServerRequestInfoImpl.CALL_INTERMEDIATE_NONE );
  383. info.setEndingPointCall(
  384. ServerRequestInfoImpl.CALL_SEND_OTHER );
  385. info.setReplyStatus( LOCATION_FORWARD.value );
  386. // For some reason, using break here causes the VM on
  387. // NT to lose track of the value of flowStackIndex
  388. // after exiting the for loop. I changed this to
  389. // check a boolean value instead and it seems to work
  390. // fine.
  391. continueProcessing = false;
  392. }
  393. catch( SystemException e ) {
  394. // as per PI spec (orbos/99-12-02 sec 5.3.1.), if
  395. // interception point throws a SystemException,
  396. // no other Interceptors' starting points are
  397. // called.
  398. flowStackIndex = i;
  399. info.setException( e );
  400. info.setIntermediatePointCall(
  401. ServerRequestInfoImpl.CALL_INTERMEDIATE_NONE );
  402. info.setEndingPointCall(
  403. ServerRequestInfoImpl.CALL_SEND_EXCEPTION );
  404. info.setReplyStatus( SYSTEM_EXCEPTION.value );
  405. // For some reason, using break here causes the VM on
  406. // NT to lose track of the value of flowStackIndex
  407. // after exiting the for loop. I changed this to
  408. // check a boolean value instead and it seems to
  409. // work fine.
  410. continueProcessing = false;
  411. }
  412. }
  413. // Remember where we left off in the flow stack:
  414. info.setFlowStackIndex( flowStackIndex );
  415. }
  416. finally {
  417. // The remaining points, ServantManager and Servant
  418. // all run in the same logical thread.
  419. current.popSlotTable( );
  420. // Now TSC and RSC are equivalent.
  421. }
  422. } // end enabled check
  423. }
  424. /**
  425. * Invokes receive_request interception points
  426. */
  427. void invokeServerInterceptorIntermediatePoint(
  428. ServerRequestInfoImpl info )
  429. {
  430. int intermediatePointCall = info.getIntermediatePointCall();
  431. // If invocation is not yet enabled, don't do anything.
  432. if( enabled && ( intermediatePointCall !=
  433. ServerRequestInfoImpl.CALL_INTERMEDIATE_NONE ) )
  434. {
  435. // NOTE: do not touch the slotStack. The RSC and TSC are
  436. // equivalent at this point.
  437. info.setCurrentExecutionPoint( info.EXECUTION_POINT_INTERMEDIATE );
  438. // Get all ServerRequestInterceptors:
  439. ServerRequestInterceptor[] serverInterceptors =
  440. (ServerRequestInterceptor[])
  441. interceptorList.getInterceptors(
  442. InterceptorList.INTERCEPTOR_TYPE_SERVER );
  443. int size = serverInterceptors.length;
  444. // Currently, there is only one server-side intermediate point
  445. // interceptor called receive_request.
  446. for( int i = 0; i < size; i++ ) {
  447. try {
  448. serverInterceptors[i].receive_request( info );
  449. }
  450. catch( ForwardRequest e ) {
  451. // as per PI spec (orbos/99-12-02 sec 5.3.1.), if
  452. // interception point throws a ForwardRequest,
  453. // no other Interceptors' intermediate points are
  454. // called and send_other is called.
  455. info.setForwardRequest( e );
  456. info.setEndingPointCall(
  457. ServerRequestInfoImpl.CALL_SEND_OTHER );
  458. info.setReplyStatus( LOCATION_FORWARD.value );
  459. break;
  460. }
  461. catch( SystemException e ) {
  462. // as per PI spec (orbos/99-12-02 sec 5.3.1.), if
  463. // interception point throws a SystemException,
  464. // no other Interceptors' starting points are
  465. // called.
  466. info.setException( e );
  467. info.setEndingPointCall(
  468. ServerRequestInfoImpl.CALL_SEND_EXCEPTION );
  469. info.setReplyStatus( SYSTEM_EXCEPTION.value );
  470. break;
  471. }
  472. }
  473. } // end enabled check
  474. }
  475. /**
  476. * Invokes either send_reply, send_exception, or send_other,
  477. * depending on the value of info.getEndingPointCall()
  478. */
  479. void invokeServerInterceptorEndingPoint( ServerRequestInfoImpl info ) {
  480. // If invocation is not yet enabled, don't do anything.
  481. if( enabled ) {
  482. try {
  483. // NOTE: do not touch the slotStack. The RSC and TSC are
  484. // equivalent at this point.
  485. // REVISIT: This is moved out to PIHandlerImpl until dispatch
  486. // path is rearchitected. It must be there so that
  487. // it always gets executed so if an interceptor raises
  488. // an exception any service contexts added in earlier points
  489. // this point get put in the exception reply (via the SC Q).
  490. //info.setCurrentExecutionPoint( info.EXECUTION_POINT_ENDING );
  491. // Get all ServerRequestInterceptors:
  492. ServerRequestInterceptor[] serverInterceptors =
  493. (ServerRequestInterceptor[])interceptorList.
  494. getInterceptors( InterceptorList.INTERCEPTOR_TYPE_SERVER );
  495. int flowStackIndex = info.getFlowStackIndex();
  496. // Determine whether we are calling
  497. // send_exception, or send_other:
  498. int endingPointCall = info.getEndingPointCall();
  499. // Only step through the interceptors whose starting points
  500. // have successfully returned.
  501. for( int i = (flowStackIndex - 1); i >= 0; i-- ) {
  502. try {
  503. switch( endingPointCall ) {
  504. case ServerRequestInfoImpl.CALL_SEND_REPLY:
  505. serverInterceptors[i].send_reply( info );
  506. break;
  507. case ServerRequestInfoImpl.CALL_SEND_EXCEPTION:
  508. serverInterceptors[i].send_exception( info );
  509. break;
  510. case ServerRequestInfoImpl.CALL_SEND_OTHER:
  511. serverInterceptors[i].send_other( info );
  512. break;
  513. }
  514. }
  515. catch( ForwardRequest e ) {
  516. // as per PI spec (orbos/99-12-02 sec 5.3.1.), if
  517. // interception point throws a ForwardException,
  518. // ending point call changes to receive_other.
  519. endingPointCall =
  520. ServerRequestInfoImpl.CALL_SEND_OTHER;
  521. info.setEndingPointCall( endingPointCall );
  522. info.setForwardRequest( e );
  523. info.setReplyStatus( LOCATION_FORWARD.value );
  524. info.setForwardRequestRaisedInEnding();
  525. }
  526. catch( SystemException e ) {
  527. // as per PI spec (orbos/99-12-02 sec 5.3.1.), if
  528. // interception point throws a SystemException,
  529. // ending point call changes to send_exception.
  530. endingPointCall =
  531. ServerRequestInfoImpl.CALL_SEND_EXCEPTION;
  532. info.setEndingPointCall( endingPointCall );
  533. info.setException( e );
  534. info.setReplyStatus( SYSTEM_EXCEPTION.value );
  535. }
  536. }
  537. // Remember that all interceptors' starting and ending points
  538. // have already been executed so we need not do anything.
  539. info.setAlreadyExecuted( true );
  540. }
  541. finally {
  542. // Get rid of the Server side RSC.
  543. current.popSlotTable();
  544. }
  545. } // end enabled check
  546. }
  547. /*
  548. **********************************************************************
  549. * Private utility methods
  550. **********************************************************************/
  551. /**
  552. * Update the client delegate in the event of a ForwardRequest, given the
  553. * information in the passed-in info object.
  554. */
  555. private void updateClientRequestDispatcherForward(
  556. ClientRequestInfoImpl info )
  557. {
  558. ForwardRequest forwardRequest = info.getForwardRequestException();
  559. // ForwardRequest may be null if the forwarded IOR is set internal
  560. // to the ClientRequestDispatcher rather than explicitly through Portable
  561. // Interceptors. In this case, we need not update the client
  562. // delegate ForwardRequest object.
  563. if( forwardRequest != null ) {
  564. org.omg.CORBA.Object object = forwardRequest.forward;
  565. // Convert the forward object into an IOR:
  566. IOR ior = ORBUtility.getIOR( object ) ;
  567. info.setLocatedIOR( ior );
  568. }
  569. }
  570. }