1. /*
  2. * @(#)PIHandlerImpl.java 1.35 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. package com.sun.corba.se.impl.interceptors;
  8. import java.util.*;
  9. import java.io.IOException;
  10. import org.omg.CORBA.Any;
  11. import org.omg.CORBA.BAD_PARAM;
  12. import org.omg.CORBA.BAD_POLICY;
  13. import org.omg.CORBA.BAD_INV_ORDER;
  14. import org.omg.CORBA.COMM_FAILURE;
  15. import org.omg.CORBA.CompletionStatus;
  16. import org.omg.CORBA.INTERNAL;
  17. import org.omg.CORBA.NVList;
  18. import org.omg.CORBA.OBJECT_NOT_EXIST;
  19. import org.omg.CORBA.ORBPackage.InvalidName;
  20. import org.omg.CORBA.SystemException;
  21. import org.omg.CORBA.UserException;
  22. import org.omg.CORBA.UNKNOWN;
  23. import org.omg.CORBA.portable.ApplicationException;
  24. import org.omg.CORBA.portable.RemarshalException;
  25. import org.omg.IOP.CodecFactory;
  26. import org.omg.PortableInterceptor.ForwardRequest;
  27. import org.omg.PortableInterceptor.Current;
  28. import org.omg.PortableInterceptor.Interceptor;
  29. import org.omg.PortableInterceptor.LOCATION_FORWARD;
  30. import org.omg.PortableInterceptor.ORBInitializer;
  31. import org.omg.PortableInterceptor.ORBInitInfo;
  32. import org.omg.PortableInterceptor.ORBInitInfoPackage.DuplicateName;
  33. import org.omg.PortableInterceptor.SUCCESSFUL;
  34. import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;
  35. import org.omg.PortableInterceptor.TRANSPORT_RETRY;
  36. import org.omg.PortableInterceptor.USER_EXCEPTION;
  37. import org.omg.PortableInterceptor.PolicyFactory;
  38. import org.omg.PortableInterceptor.ObjectReferenceTemplate ;
  39. import com.sun.corba.se.pept.encoding.OutputObject;
  40. import com.sun.corba.se.spi.ior.IOR;
  41. import com.sun.corba.se.spi.ior.ObjectKeyTemplate;
  42. import com.sun.corba.se.spi.oa.ObjectAdapter;
  43. import com.sun.corba.se.spi.orb.ORB;
  44. import com.sun.corba.se.spi.orbutil.closure.ClosureFactory;
  45. import com.sun.corba.se.spi.protocol.CorbaMessageMediator;
  46. import com.sun.corba.se.spi.protocol.ForwardException;
  47. import com.sun.corba.se.spi.protocol.PIHandler;
  48. import com.sun.corba.se.spi.logging.CORBALogDomains;
  49. import com.sun.corba.se.impl.logging.InterceptorsSystemException;
  50. import com.sun.corba.se.impl.logging.ORBUtilSystemException;
  51. import com.sun.corba.se.impl.logging.OMGSystemException;
  52. import com.sun.corba.se.impl.corba.RequestImpl;
  53. import com.sun.corba.se.impl.orbutil.ORBClassLoader;
  54. import com.sun.corba.se.impl.orbutil.ORBConstants;
  55. import com.sun.corba.se.impl.orbutil.ORBUtility;
  56. import com.sun.corba.se.impl.orbutil.StackImpl;
  57. import com.sun.corba.se.impl.protocol.giopmsgheaders.ReplyMessage;
  58. /**
  59. * Provides portable interceptor functionality.
  60. */
  61. public class PIHandlerImpl implements PIHandler
  62. {
  63. // REVISIT - delete these after framework merging.
  64. boolean printPushPopEnabled = false;
  65. int pushLevel = 0;
  66. private void printPush()
  67. {
  68. if (! printPushPopEnabled) return;
  69. printSpaces(pushLevel);
  70. pushLevel++;
  71. System.out.println("PUSH");
  72. }
  73. private void printPop()
  74. {
  75. if (! printPushPopEnabled) return;
  76. pushLevel--;
  77. printSpaces(pushLevel);
  78. System.out.println("POP");
  79. }
  80. private void printSpaces(int n)
  81. {
  82. for (int i = 0; i < n; i++) {
  83. System.out.print(" ");
  84. }
  85. }
  86. private ORB orb ;
  87. InterceptorsSystemException wrapper ;
  88. ORBUtilSystemException orbutilWrapper ;
  89. OMGSystemException omgWrapper ;
  90. // A unique id used in ServerRequestInfo.
  91. // This does not correspond to the GIOP request id.
  92. private int serverRequestIdCounter = 0;
  93. // Stores the codec factory for producing codecs
  94. CodecFactory codecFactory = null;
  95. // The arguments passed to the application's main method. May be null.
  96. // This is used for ORBInitializers and set from set_parameters.
  97. String[] arguments = null;
  98. // The list of portable interceptors, organized by type:
  99. private InterceptorList interceptorList;
  100. // Cached information for optimization - do we have any interceptors
  101. // registered of the given types? Set during ORB initialization.
  102. private boolean hasIORInterceptors;
  103. private boolean hasClientInterceptors; // temp always true
  104. private boolean hasServerInterceptors;
  105. // The class responsible for invoking interceptors
  106. private InterceptorInvoker interceptorInvoker;
  107. // There will be one PICurrent instantiated for every ORB.
  108. private PICurrent current;
  109. // This table contains a list of PolicyFactories registered using
  110. // ORBInitInfo.registerPolicyFactory() method.
  111. // Key for the table is PolicyType which is an Integer
  112. // Value is PolicyFactory.
  113. private HashMap policyFactoryTable;
  114. // Table to convert from a ReplyMessage.? to a PI replyStatus short.
  115. // Note that this table relies on the order and constants of
  116. // ReplyMessage not to change.
  117. private final static short REPLY_MESSAGE_TO_PI_REPLY_STATUS[] = {
  118. SUCCESSFUL.value, // = ReplyMessage.NO_EXCEPTION
  119. USER_EXCEPTION.value, // = ReplyMessage.USER_EXCEPTION
  120. SYSTEM_EXCEPTION.value, // = ReplyMessage.SYSTEM_EXCEPTION
  121. LOCATION_FORWARD.value, // = ReplyMessage.LOCATION_FORWARD
  122. LOCATION_FORWARD.value, // = ReplyMessage.LOCATION_FORWARD_PERM
  123. TRANSPORT_RETRY.value // = ReplyMessage.NEEDS_ADDRESSING_MODE
  124. };
  125. // ThreadLocal containing a stack to store client request info objects
  126. // and a disable count.
  127. private ThreadLocal threadLocalClientRequestInfoStack =
  128. new ThreadLocal() {
  129. protected Object initialValue() {
  130. return new RequestInfoStack();
  131. }
  132. };
  133. // ThreadLocal containing the current server request info object.
  134. private ThreadLocal threadLocalServerRequestInfoStack =
  135. new ThreadLocal() {
  136. protected Object initialValue() {
  137. return new RequestInfoStack();
  138. }
  139. };
  140. // Class to contain all ThreadLocal data for ClientRequestInfo
  141. // maintenance.
  142. //
  143. // We use an ArrayList instead since it is not thread-safe.
  144. // RequestInfoStack is used quite frequently.
  145. private final class RequestInfoStack extends Stack {
  146. // Number of times a request has been made to disable interceptors.
  147. // When this reaches 0, interception hooks are disabled. Any higher
  148. // value indicates they are enabled.
  149. // NOTE: The is only currently used on the client side.
  150. public int disableCount = 0;
  151. }
  152. public PIHandlerImpl( ORB orb, String[] args ) {
  153. this.orb = orb ;
  154. wrapper = InterceptorsSystemException.get( orb,
  155. CORBALogDomains.RPC_PROTOCOL ) ;
  156. orbutilWrapper = ORBUtilSystemException.get( orb,
  157. CORBALogDomains.RPC_PROTOCOL ) ;
  158. omgWrapper = OMGSystemException.get( orb,
  159. CORBALogDomains.RPC_PROTOCOL ) ;
  160. arguments = args ;
  161. // Create codec factory:
  162. codecFactory = new CodecFactoryImpl( orb );
  163. // Create new interceptor list:
  164. interceptorList = new InterceptorList( wrapper );
  165. // Create a new PICurrent.
  166. current = new PICurrent( orb );
  167. // Create new interceptor invoker, initially disabled:
  168. interceptorInvoker = new InterceptorInvoker( orb, interceptorList,
  169. current );
  170. // Register the PI current and Codec factory objects
  171. orb.getLocalResolver().register( ORBConstants.PI_CURRENT_NAME,
  172. ClosureFactory.makeConstant( current ) ) ;
  173. orb.getLocalResolver().register( ORBConstants.CODEC_FACTORY_NAME,
  174. ClosureFactory.makeConstant( codecFactory ) ) ;
  175. }
  176. public void initialize() {
  177. // If we have any orb initializers, make use of them:
  178. if( orb.getORBData().getORBInitializers() != null ) {
  179. // Create the ORBInitInfo object to pass to ORB intializers:
  180. ORBInitInfoImpl orbInitInfo = createORBInitInfo();
  181. // Make sure get_slot and set_slot are not called from within
  182. // ORB initializers:
  183. current.setORBInitializing( true );
  184. // Call pre_init on all ORB initializers:
  185. preInitORBInitializers( orbInitInfo );
  186. // Call post_init on all ORB initializers:
  187. postInitORBInitializers( orbInitInfo );
  188. // Proprietary: sort interceptors:
  189. interceptorList.sortInterceptors();
  190. // Re-enable get_slot and set_slot to be called from within
  191. // ORB initializers:
  192. current.setORBInitializing( false );
  193. // Ensure nobody makes any more calls on this object.
  194. orbInitInfo.setStage( ORBInitInfoImpl.STAGE_CLOSED );
  195. // Set cached flags indicating whether we have interceptors
  196. // registered of a given type.
  197. hasIORInterceptors = interceptorList.hasInterceptorsOfType(
  198. InterceptorList.INTERCEPTOR_TYPE_IOR );
  199. // XXX This must always be true, so that using the new generic
  200. // RPC framework can pass info between the PI stack and the
  201. // framework invocation stack. Temporary until Harold fixes
  202. // this. Note that this must never be true until after the
  203. // ORBInitializer instances complete executing.
  204. //hasClientInterceptors = interceptorList.hasInterceptorsOfType(
  205. //InterceptorList.INTERCEPTOR_TYPE_CLIENT );
  206. hasClientInterceptors = true;
  207. hasServerInterceptors = interceptorList.hasInterceptorsOfType(
  208. InterceptorList.INTERCEPTOR_TYPE_SERVER );
  209. // Enable interceptor invoker (not necessary if no interceptors
  210. // are registered). This should be the last stage of ORB
  211. // initialization.
  212. interceptorInvoker.setEnabled( true );
  213. }
  214. }
  215. /**
  216. * ptc/00-08-06 p 205: "When an application calls ORB::destroy, the ORB
  217. * 1) waits for all requests in progress to complete
  218. * 2) calls the Interceptor::destroy operation for each interceptor
  219. * 3) completes destruction of the ORB"
  220. *
  221. * This must be called at the end of ORB.destroy. Note that this is not
  222. * part of the PIHandler interface, since ORBImpl implements the ORB interface.
  223. */
  224. public void destroyInterceptors() {
  225. interceptorList.destroyAll();
  226. }
  227. public void objectAdapterCreated( ObjectAdapter oa )
  228. {
  229. if (!hasIORInterceptors)
  230. return ;
  231. interceptorInvoker.objectAdapterCreated( oa ) ;
  232. }
  233. public void adapterManagerStateChanged( int managerId,
  234. short newState )
  235. {
  236. if (!hasIORInterceptors)
  237. return ;
  238. interceptorInvoker.adapterManagerStateChanged( managerId, newState ) ;
  239. }
  240. public void adapterStateChanged( ObjectReferenceTemplate[]
  241. templates, short newState )
  242. {
  243. if (!hasIORInterceptors)
  244. return ;
  245. interceptorInvoker.adapterStateChanged( templates, newState ) ;
  246. }
  247. /*
  248. *****************
  249. * Client PI hooks
  250. *****************/
  251. public void disableInterceptorsThisThread() {
  252. if( !hasClientInterceptors ) return;
  253. RequestInfoStack infoStack =
  254. (RequestInfoStack)threadLocalClientRequestInfoStack.get();
  255. infoStack.disableCount++;
  256. }
  257. public void enableInterceptorsThisThread() {
  258. if( !hasClientInterceptors ) return;
  259. RequestInfoStack infoStack =
  260. (RequestInfoStack)threadLocalClientRequestInfoStack.get();
  261. infoStack.disableCount--;
  262. }
  263. public void invokeClientPIStartingPoint()
  264. throws RemarshalException
  265. {
  266. if( !hasClientInterceptors ) return;
  267. if( !isClientPIEnabledForThisThread() ) return;
  268. // Invoke the starting interception points and record exception
  269. // and reply status info in the info object:
  270. ClientRequestInfoImpl info = peekClientRequestInfoImplStack();
  271. interceptorInvoker.invokeClientInterceptorStartingPoint( info );
  272. // Check reply status. If we will not have another chance later
  273. // to invoke the client ending points, do it now.
  274. short replyStatus = info.getReplyStatus();
  275. if( (replyStatus == SYSTEM_EXCEPTION.value) ||
  276. (replyStatus == LOCATION_FORWARD.value) )
  277. {
  278. // Note: Transport retry cannot happen here since this happens
  279. // before the request hits the wire.
  280. Exception exception = invokeClientPIEndingPoint(
  281. convertPIReplyStatusToReplyMessage( replyStatus ),
  282. info.getException() );
  283. if( exception == null ) {
  284. // Do not throw anything. Otherwise, it must be a
  285. // SystemException, UserException or RemarshalException.
  286. } if( exception instanceof SystemException ) {
  287. throw (SystemException)exception;
  288. } else if( exception instanceof RemarshalException ) {
  289. throw (RemarshalException)exception;
  290. } else if( (exception instanceof UserException) ||
  291. (exception instanceof ApplicationException) ) {
  292. // It should not be possible for an interceptor to throw
  293. // a UserException. By asserting instead of throwing the
  294. // UserException, we need not declare anything but
  295. // RemarshalException in the throws clause.
  296. throw wrapper.exceptionInvalid() ;
  297. }
  298. }
  299. else if( replyStatus != ClientRequestInfoImpl.UNINITIALIZED ) {
  300. throw wrapper.replyStatusNotInit() ;
  301. }
  302. }
  303. public Exception invokeClientPIEndingPoint(
  304. int replyStatus, Exception exception )
  305. {
  306. if( !hasClientInterceptors ) return exception;
  307. if( !isClientPIEnabledForThisThread() ) return exception;
  308. // Translate ReplyMessage.replyStatus into PI replyStatus:
  309. // Note: this is also an assertion to make sure a valid replyStatus
  310. // is passed in (IndexOutOfBoundsException will be thrown otherwise)
  311. short piReplyStatus = REPLY_MESSAGE_TO_PI_REPLY_STATUS[replyStatus];
  312. // Invoke the ending interception points and record exception
  313. // and reply status info in the info object:
  314. ClientRequestInfoImpl info = peekClientRequestInfoImplStack();
  315. info.setReplyStatus( piReplyStatus );
  316. info.setException( exception );
  317. interceptorInvoker.invokeClientInterceptorEndingPoint( info );
  318. piReplyStatus = info.getReplyStatus();
  319. // Check reply status:
  320. if( (piReplyStatus == LOCATION_FORWARD.value) ||
  321. (piReplyStatus == TRANSPORT_RETRY.value) )
  322. {
  323. // If this is a forward or a retry, reset and reuse
  324. // info object:
  325. info.reset();
  326. info.setRetryRequest( true );
  327. // ... and return a RemarshalException so the orb internals know
  328. exception = new RemarshalException();
  329. }
  330. else if( (piReplyStatus == SYSTEM_EXCEPTION.value) ||
  331. (piReplyStatus == USER_EXCEPTION.value) )
  332. {
  333. exception = info.getException();
  334. }
  335. return exception;
  336. }
  337. public void initiateClientPIRequest( boolean diiRequest ) {
  338. if( !hasClientInterceptors ) return;
  339. if( !isClientPIEnabledForThisThread() ) return;
  340. // Get the most recent info object from the thread local
  341. // ClientRequestInfoImpl stack:
  342. RequestInfoStack infoStack =
  343. (RequestInfoStack)threadLocalClientRequestInfoStack.get();
  344. ClientRequestInfoImpl info = null;
  345. if( !infoStack.empty() ) info =
  346. (ClientRequestInfoImpl)infoStack.peek();
  347. if( !diiRequest && (info != null) && info.isDIIInitiate() ) {
  348. // In RequestImpl.doInvocation we already called
  349. // initiateClientPIRequest( true ), so ignore this initiate.
  350. info.setDIIInitiate( false );
  351. }
  352. else {
  353. // If there is no info object or if we are not retrying a request,
  354. // push a new ClientRequestInfoImpl on the stack:
  355. if( (info == null) || !info.getRetryRequest() ) {
  356. info = new ClientRequestInfoImpl( orb );
  357. infoStack.push( info );
  358. printPush();
  359. // Note: the entry count is automatically initialized to 0.
  360. }
  361. // Reset the retry request flag so that recursive calls will
  362. // push a new info object, and bump up entry count so we know
  363. // when to pop this info object:
  364. info.setRetryRequest( false );
  365. info.incrementEntryCount();
  366. // If this is a DII request, make sure we ignore the next initiate.
  367. if( diiRequest ) {
  368. info.setDIIInitiate( true );
  369. }
  370. }
  371. }
  372. public void cleanupClientPIRequest() {
  373. if( !hasClientInterceptors ) return;
  374. if( !isClientPIEnabledForThisThread() ) return;
  375. ClientRequestInfoImpl info = peekClientRequestInfoImplStack();
  376. // If the replyStatus has not yet been set, this is an indication
  377. // that the ORB threw an exception before we had a chance to
  378. // invoke the client interceptor ending points.
  379. //
  380. // _REVISIT_ We cannot handle any exceptions or ForwardRequests
  381. // flagged by the ending points here because there is no way
  382. // to gracefully handle this in any of the calling code.
  383. // This is a rare corner case, so we will ignore this for now.
  384. short replyStatus = info.getReplyStatus();
  385. if( replyStatus == info.UNINITIALIZED ) {
  386. invokeClientPIEndingPoint( ReplyMessage.SYSTEM_EXCEPTION,
  387. wrapper.unknownRequestInvoke(
  388. CompletionStatus.COMPLETED_MAYBE ) ) ;
  389. }
  390. // Decrement entry count, and if it is zero, pop it from the stack.
  391. info.decrementEntryCount();
  392. if( info.getEntryCount() == 0 ) {
  393. RequestInfoStack infoStack =
  394. (RequestInfoStack)threadLocalClientRequestInfoStack.get();
  395. infoStack.pop();
  396. printPop();
  397. }
  398. }
  399. public void setClientPIInfo(CorbaMessageMediator messageMediator)
  400. {
  401. if( !hasClientInterceptors ) return;
  402. if( !isClientPIEnabledForThisThread() ) return;
  403. peekClientRequestInfoImplStack().setInfo(messageMediator);
  404. }
  405. public void setClientPIInfo( RequestImpl requestImpl ) {
  406. if( !hasClientInterceptors ) return;
  407. if( !isClientPIEnabledForThisThread() ) return;
  408. peekClientRequestInfoImplStack().setDIIRequest( requestImpl );
  409. }
  410. /*
  411. *****************
  412. * Server PI hooks
  413. *****************/
  414. public void invokeServerPIStartingPoint()
  415. {
  416. if( !hasServerInterceptors ) return;
  417. ServerRequestInfoImpl info = peekServerRequestInfoImplStack();
  418. interceptorInvoker.invokeServerInterceptorStartingPoint( info );
  419. // Handle SystemException or ForwardRequest:
  420. serverPIHandleExceptions( info );
  421. }
  422. public void invokeServerPIIntermediatePoint()
  423. {
  424. if( !hasServerInterceptors ) return;
  425. ServerRequestInfoImpl info = peekServerRequestInfoImplStack();
  426. interceptorInvoker.invokeServerInterceptorIntermediatePoint( info );
  427. // Clear servant from info object so that the user has control over
  428. // its lifetime:
  429. info.releaseServant();
  430. // Handle SystemException or ForwardRequest:
  431. serverPIHandleExceptions( info );
  432. }
  433. public void invokeServerPIEndingPoint( ReplyMessage replyMessage )
  434. {
  435. if( !hasServerInterceptors ) return;
  436. ServerRequestInfoImpl info = peekServerRequestInfoImplStack();
  437. // REVISIT: This needs to be done "early" for the following workaround.
  438. info.setReplyMessage( replyMessage );
  439. // REVISIT: This was done inside of invokeServerInterceptorEndingPoint
  440. // but needs to be here for now. See comment in that method for why.
  441. info.setCurrentExecutionPoint( info.EXECUTION_POINT_ENDING );
  442. // It is possible we might have entered this method more than
  443. // once (e.g. if an ending point threw a SystemException, then
  444. // a new ServerResponseImpl is created).
  445. if( !info.getAlreadyExecuted() ) {
  446. int replyStatus = replyMessage.getReplyStatus();
  447. // Translate ReplyMessage.replyStatus into PI replyStatus:
  448. // Note: this is also an assertion to make sure a valid
  449. // replyStatus is passed in (IndexOutOfBoundsException will be
  450. // thrown otherwise)
  451. short piReplyStatus =
  452. REPLY_MESSAGE_TO_PI_REPLY_STATUS[replyStatus];
  453. // Make forwarded IOR available to interceptors, if applicable:
  454. if( ( piReplyStatus == LOCATION_FORWARD.value ) ||
  455. ( piReplyStatus == TRANSPORT_RETRY.value ) )
  456. {
  457. info.setForwardRequest( replyMessage.getIOR() );
  458. }
  459. // REVISIT: Do early above for now.
  460. // Make reply message available to interceptors:
  461. //info.setReplyMessage( replyMessage );
  462. // Remember exception so we can tell if an interceptor changed it.
  463. Exception prevException = info.getException();
  464. // _REVISIT_ We do not have access to the User Exception at
  465. // this point, so treat it as an UNKNOWN for now.
  466. // Note that if this is a DSI call, we do have the user exception.
  467. if( !info.isDynamic() &&
  468. (piReplyStatus == USER_EXCEPTION.value) )
  469. {
  470. info.setException( omgWrapper.unknownUserException(
  471. CompletionStatus.COMPLETED_MAYBE ) ) ;
  472. }
  473. // Invoke the ending interception points:
  474. info.setReplyStatus( piReplyStatus );
  475. interceptorInvoker.invokeServerInterceptorEndingPoint( info );
  476. short newPIReplyStatus = info.getReplyStatus();
  477. Exception newException = info.getException();
  478. // Check reply status. If an interceptor threw a SystemException
  479. // and it is different than the one that we came in with,
  480. // rethrow it so the proper response can be constructed:
  481. if( ( newPIReplyStatus == SYSTEM_EXCEPTION.value ) &&
  482. ( newException != prevException ) )
  483. {
  484. throw (SystemException)newException;
  485. }
  486. // If we are to forward the location:
  487. if( newPIReplyStatus == LOCATION_FORWARD.value ) {
  488. if( piReplyStatus != LOCATION_FORWARD.value ) {
  489. // Treat a ForwardRequest as a ForwardException.
  490. IOR ior = info.getForwardRequestIOR();
  491. throw new ForwardException( orb, ior ) ;
  492. }
  493. else if( info.isForwardRequestRaisedInEnding() ) {
  494. // Treat a ForwardRequest by changing the IOR.
  495. replyMessage.setIOR( info.getForwardRequestIOR() );
  496. }
  497. }
  498. }
  499. }
  500. public void setServerPIInfo( Exception exception ) {
  501. if( !hasServerInterceptors ) return;
  502. ServerRequestInfoImpl info = peekServerRequestInfoImplStack();
  503. info.setException( exception );
  504. }
  505. public void setServerPIInfo( NVList arguments )
  506. {
  507. if( !hasServerInterceptors ) return;
  508. ServerRequestInfoImpl info = peekServerRequestInfoImplStack();
  509. info.setDSIArguments( arguments );
  510. }
  511. public void setServerPIExceptionInfo( Any exception )
  512. {
  513. if( !hasServerInterceptors ) return;
  514. ServerRequestInfoImpl info = peekServerRequestInfoImplStack();
  515. info.setDSIException( exception );
  516. }
  517. public void setServerPIInfo( Any result )
  518. {
  519. if( !hasServerInterceptors ) return;
  520. ServerRequestInfoImpl info = peekServerRequestInfoImplStack();
  521. info.setDSIResult( result );
  522. }
  523. public void initializeServerPIInfo( CorbaMessageMediator request,
  524. ObjectAdapter oa, byte[] objectId, ObjectKeyTemplate oktemp )
  525. {
  526. if( !hasServerInterceptors ) return;
  527. RequestInfoStack infoStack =
  528. (RequestInfoStack)threadLocalServerRequestInfoStack.get();
  529. ServerRequestInfoImpl info = new ServerRequestInfoImpl( orb );
  530. infoStack.push( info );
  531. printPush();
  532. // Notify request object that once response is constructed, make
  533. // sure we execute ending points.
  534. request.setExecutePIInResponseConstructor( true );
  535. info.setInfo( request, oa, objectId, oktemp );
  536. }
  537. public void setServerPIInfo( java.lang.Object servant,
  538. String targetMostDerivedInterface )
  539. {
  540. if( !hasServerInterceptors ) return;
  541. ServerRequestInfoImpl info = peekServerRequestInfoImplStack();
  542. info.setInfo( servant, targetMostDerivedInterface );
  543. }
  544. public void cleanupServerPIRequest() {
  545. if( !hasServerInterceptors ) return;
  546. RequestInfoStack infoStack =
  547. (RequestInfoStack)threadLocalServerRequestInfoStack.get();
  548. infoStack.pop();
  549. printPop();
  550. }
  551. /*
  552. **********************************************************************
  553. * The following methods are private utility methods.
  554. ************************************************************************/
  555. /**
  556. * Handles exceptions for the starting and intermediate points for
  557. * server request interceptors. This is common code that has been
  558. * factored out into this utility method.
  559. * <p>
  560. * This method will NOT work for ending points.
  561. */
  562. private void serverPIHandleExceptions( ServerRequestInfoImpl info )
  563. {
  564. int endingPointCall = info.getEndingPointCall();
  565. if(endingPointCall == ServerRequestInfoImpl.CALL_SEND_EXCEPTION) {
  566. // If a system exception was thrown, throw it to caller:
  567. throw (SystemException)info.getException();
  568. }
  569. else if( (endingPointCall == ServerRequestInfoImpl.CALL_SEND_OTHER) &&
  570. (info.getForwardRequestException() != null) )
  571. {
  572. // If an interceptor throws a forward request, convert it
  573. // into a ForwardException for easier handling:
  574. IOR ior = info.getForwardRequestIOR();
  575. throw new ForwardException( orb, ior );
  576. }
  577. }
  578. /**
  579. * Utility method to convert a PI reply status short to a ReplyMessage
  580. * constant. This is a reverse lookup on the table defined in
  581. * REPLY_MESSAGE_TO_PI_REPLY_STATUS. The reverse lookup need not be
  582. * performed as quickly since it is only executed in exception
  583. * conditions.
  584. */
  585. private int convertPIReplyStatusToReplyMessage( short replyStatus ) {
  586. int result = 0;
  587. for( int i = 0; i < REPLY_MESSAGE_TO_PI_REPLY_STATUS.length; i++ ) {
  588. if( REPLY_MESSAGE_TO_PI_REPLY_STATUS[i] == replyStatus ) {
  589. result = i;
  590. break;
  591. }
  592. }
  593. return result;
  594. }
  595. /**
  596. * Convenience method to get the ClientRequestInfoImpl object off the
  597. * top of the ThreadLocal stack. Throws an INTERNAL exception if
  598. * the Info stack is empty.
  599. */
  600. private ClientRequestInfoImpl peekClientRequestInfoImplStack() {
  601. RequestInfoStack infoStack =
  602. (RequestInfoStack)threadLocalClientRequestInfoStack.get();
  603. ClientRequestInfoImpl info = null;
  604. if( !infoStack.empty() ) {
  605. info = (ClientRequestInfoImpl)infoStack.peek();
  606. } else {
  607. throw wrapper.clientInfoStackNull() ;
  608. }
  609. return info;
  610. }
  611. /**
  612. * Convenience method to get the ServerRequestInfoImpl object off the
  613. * top of the ThreadLocal stack. Returns null if there are none.
  614. */
  615. private ServerRequestInfoImpl peekServerRequestInfoImplStack() {
  616. RequestInfoStack infoStack =
  617. (RequestInfoStack)threadLocalServerRequestInfoStack.get();
  618. ServerRequestInfoImpl info = null;
  619. if( !infoStack.empty() ) {
  620. info = (ServerRequestInfoImpl)infoStack.peek();
  621. } else {
  622. throw wrapper.serverInfoStackNull() ;
  623. }
  624. return info;
  625. }
  626. /**
  627. * Convenience method to determine whether Client PI is enabled
  628. * for requests on this thread.
  629. */
  630. private boolean isClientPIEnabledForThisThread() {
  631. RequestInfoStack infoStack =
  632. (RequestInfoStack)threadLocalClientRequestInfoStack.get();
  633. return (infoStack.disableCount == 0);
  634. }
  635. /**
  636. * Call pre_init on all ORB initializers
  637. */
  638. private void preInitORBInitializers( ORBInitInfoImpl info ) {
  639. // Inform ORBInitInfo we are in pre_init stage
  640. info.setStage( ORBInitInfoImpl.STAGE_PRE_INIT );
  641. // Step through each initializer instantiation and call its
  642. // pre_init. Ignore any exceptions.
  643. for( int i = 0; i < orb.getORBData().getORBInitializers().length;
  644. i++ ) {
  645. ORBInitializer init = orb.getORBData().getORBInitializers()[i];
  646. if( init != null ) {
  647. try {
  648. init.pre_init( info );
  649. }
  650. catch( Exception e ) {
  651. // As per orbos/99-12-02, section 9.3.1.2, "If there are
  652. // any exceptions, the ORB shall ignore them and proceed."
  653. }
  654. }
  655. }
  656. }
  657. /**
  658. * Call post_init on all ORB initializers
  659. */
  660. private void postInitORBInitializers( ORBInitInfoImpl info ) {
  661. // Inform ORBInitInfo we are in post_init stage
  662. info.setStage( ORBInitInfoImpl.STAGE_POST_INIT );
  663. // Step through each initializer instantiation and call its post_init.
  664. // Ignore any exceptions.
  665. for( int i = 0; i < orb.getORBData().getORBInitializers().length;
  666. i++ ) {
  667. ORBInitializer init = orb.getORBData().getORBInitializers()[i];
  668. if( init != null ) {
  669. try {
  670. init.post_init( info );
  671. }
  672. catch( Exception e ) {
  673. // As per orbos/99-12-02, section 9.3.1.2, "If there are
  674. // any exceptions, the ORB shall ignore them and proceed."
  675. }
  676. }
  677. }
  678. }
  679. /**
  680. * Creates the ORBInitInfo object to be passed to ORB intializers'
  681. * pre_init and post_init methods
  682. */
  683. private ORBInitInfoImpl createORBInitInfo() {
  684. ORBInitInfoImpl result = null;
  685. // arguments comes from set_parameters. May be null.
  686. // _REVISIT_ The spec does not specify which ID this is to be.
  687. // We currently get this from the corba.ORB, which reads it from
  688. // the ORB_ID_PROPERTY property.
  689. String orbId = orb.getORBData().getORBId() ;
  690. result = new ORBInitInfoImpl( orb, arguments, orbId, codecFactory );
  691. return result;
  692. }
  693. /**
  694. * Called by ORBInitInfo when an interceptor needs to be registered.
  695. * The type is one of:
  696. * <ul>
  697. * <li>INTERCEPTOR_TYPE_CLIENT - ClientRequestInterceptor
  698. * <li>INTERCEPTOR_TYPE_SERVER - ServerRequestInterceptor
  699. * <li>INTERCEPTOR_TYPE_IOR - IORInterceptor
  700. * </ul>
  701. *
  702. * @exception DuplicateName Thrown if an interceptor of the given
  703. * name already exists for the given type.
  704. */
  705. public void register_interceptor( Interceptor interceptor, int type )
  706. throws DuplicateName
  707. {
  708. // We will assume interceptor is not null, since it is called
  709. // internally.
  710. if( (type >= InterceptorList.NUM_INTERCEPTOR_TYPES) || (type < 0) ) {
  711. throw wrapper.typeOutOfRange( new Integer( type ) ) ;
  712. }
  713. String interceptorName = interceptor.name();
  714. if( interceptorName == null ) {
  715. throw wrapper.nameNull() ;
  716. }
  717. // Register with interceptor list:
  718. interceptorList.register_interceptor( interceptor, type );
  719. }
  720. public Current getPICurrent( ) {
  721. return current;
  722. }
  723. /**
  724. * Called when an invalid null parameter was passed. Throws a
  725. * BAD_PARAM with a minor code of 1
  726. */
  727. private void nullParam()
  728. throws BAD_PARAM
  729. {
  730. throw orbutilWrapper.nullParam() ;
  731. }
  732. /** This is the implementation of standard API defined in org.omg.CORBA.ORB
  733. * class. This method finds the Policy Factory for the given Policy Type
  734. * and instantiates the Policy object from the Factory. It will throw
  735. * PolicyError exception, If the PolicyFactory for the given type is
  736. * not registered.
  737. * _REVISIT_, Once Policy Framework work is completed, Reorganize
  738. * this method to com.sun.corba.se.spi.orb.ORB.
  739. */
  740. public org.omg.CORBA.Policy create_policy(int type, org.omg.CORBA.Any val)
  741. throws org.omg.CORBA.PolicyError
  742. {
  743. if( val == null ) {
  744. nullParam( );
  745. }
  746. if( policyFactoryTable == null ) {
  747. throw new org.omg.CORBA.PolicyError(
  748. "There is no PolicyFactory Registered for type " + type,
  749. BAD_POLICY.value );
  750. }
  751. PolicyFactory factory = (PolicyFactory)policyFactoryTable.get(
  752. new Integer(type) );
  753. if( factory == null ) {
  754. throw new org.omg.CORBA.PolicyError(
  755. " Could Not Find PolicyFactory for the Type " + type,
  756. BAD_POLICY.value);
  757. }
  758. org.omg.CORBA.Policy policy = factory.create_policy( type, val );
  759. return policy;
  760. }
  761. /** This method registers the Policy Factory in the policyFactoryTable,
  762. * which is a HashMap. This method is made package private, because
  763. * it is used internally by the Interceptors.
  764. */
  765. public void registerPolicyFactory( int type, PolicyFactory factory ) {
  766. if( policyFactoryTable == null ) {
  767. policyFactoryTable = new HashMap();
  768. }
  769. Integer key = new Integer( type );
  770. java.lang.Object val = policyFactoryTable.get( key );
  771. if( val == null ) {
  772. policyFactoryTable.put( key, factory );
  773. }
  774. else {
  775. throw omgWrapper.policyFactoryRegFailed( new Integer( type ) ) ;
  776. }
  777. }
  778. public synchronized int allocateServerRequestId ()
  779. {
  780. return serverRequestIdCounter++;
  781. }
  782. }