1. /*
  2. * @(#)ServerRequestInfoImpl.java 1.37 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. package com.sun.corba.se.internal.Interceptors;
  8. import org.omg.CORBA.Any;
  9. import org.omg.CORBA.BAD_INV_ORDER;
  10. import org.omg.CORBA.CompletionStatus;
  11. import org.omg.CORBA.INTERNAL;
  12. import org.omg.CORBA.LocalObject;
  13. import org.omg.CORBA.NO_IMPLEMENT;
  14. import org.omg.CORBA.NO_RESOURCES;
  15. import org.omg.CORBA.NVList;
  16. import org.omg.CORBA.Object;
  17. import org.omg.CORBA.Policy;
  18. import org.omg.CORBA.TypeCode;
  19. import org.omg.CORBA.portable.ObjectImpl;
  20. import org.omg.PortableServer.Servant;
  21. import org.omg.IOP.TaggedProfile;
  22. import org.omg.IOP.ServiceContext;
  23. import com.sun.corba.se.internal.iiop.messages.ReplyMessage;
  24. import org.omg.Dynamic.Parameter;
  25. import org.omg.PortableInterceptor.InvalidSlot;
  26. import org.omg.PortableInterceptor.ServerRequestInfo;
  27. import org.omg.PortableInterceptor.LOCATION_FORWARD;
  28. import org.omg.PortableInterceptor.SUCCESSFUL;
  29. import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;
  30. import org.omg.PortableInterceptor.TRANSPORT_RETRY;
  31. import org.omg.PortableInterceptor.USER_EXCEPTION;
  32. import com.sun.corba.se.internal.core.ServerRequest;
  33. import com.sun.corba.se.internal.core.ServiceContexts;
  34. import com.sun.corba.se.internal.POA.POAImpl;
  35. import java.util.*;
  36. /**
  37. * Implementation of the ServerRequestInfo interface as specified in
  38. * orbos/99-12-02 section 5.4.3.
  39. */
  40. public final class ServerRequestInfoImpl
  41. extends RequestInfoImpl
  42. implements ServerRequestInfo
  43. {
  44. // The available constants for startingPointCall
  45. static final int CALL_RECEIVE_REQUEST_SERVICE_CONTEXT = 0;
  46. // The available constants for intermediatePointCall. The default (0)
  47. // is receive_request, but can be set to none on demand.
  48. static final int CALL_RECEIVE_REQUEST = 0;
  49. static final int CALL_INTERMEDIATE_NONE = 1;
  50. // The available constants for endingPointCall
  51. static final int CALL_SEND_REPLY = 0;
  52. static final int CALL_SEND_EXCEPTION = 1;
  53. static final int CALL_SEND_OTHER = 2;
  54. //////////////////////////////////////////////////////////////////////
  55. //
  56. // NOTE: IF AN ATTRIBUTE IS ADDED, PLEASE UPDATE RESET();
  57. //
  58. //////////////////////////////////////////////////////////////////////
  59. // Set to true if the server ending point raised ForwardRequest at some
  60. // point in the ending point.
  61. private boolean forwardRequestRaisedInEnding;
  62. // Sources of server request information:
  63. private ServerRequest request;
  64. private java.lang.Object servant;
  65. private byte[] objectId;
  66. private byte[] adapterId;
  67. private ArrayList addReplyServiceContextQueue;
  68. private ReplyMessage replyMessage;
  69. private String targetMostDerivedInterface;
  70. private NVList dsiArguments;
  71. private Any dsiResult;
  72. private Any dsiException;
  73. private boolean isDynamic;
  74. private POAImpl poaimpl;
  75. private int serverRequestId;
  76. // Cached information:
  77. private Parameter[] cachedArguments;
  78. private Any cachedSendingException;
  79. // key = Integer, value = IOP.ServiceContext.
  80. private HashMap cachedRequestServiceContexts;
  81. // key = Integer, value = IOP.ServiceContext.
  82. private HashMap cachedReplyServiceContexts;
  83. //////////////////////////////////////////////////////////////////////
  84. //
  85. // NOTE: IF AN ATTRIBUTE IS ADDED, PLEASE UPDATE RESET();
  86. //
  87. //////////////////////////////////////////////////////////////////////
  88. /**
  89. * Reset the info object so that it can be reused for a retry,
  90. * for example.
  91. */
  92. void reset() {
  93. super.reset();
  94. // Please keep these in the same order as declared above.
  95. forwardRequestRaisedInEnding = false;
  96. request = null;
  97. servant = null;
  98. objectId = null;
  99. adapterId = null;
  100. addReplyServiceContextQueue = null;
  101. replyMessage = null;
  102. targetMostDerivedInterface = null;
  103. dsiArguments = null;
  104. dsiResult = null;
  105. dsiException = null;
  106. isDynamic = false;
  107. poaimpl = null;
  108. serverRequestId = piOrb.allocateServerRequestId();
  109. // reset cached attributes:
  110. cachedArguments = null;
  111. cachedSendingException = null;
  112. cachedRequestServiceContexts = null;
  113. cachedReplyServiceContexts = null;
  114. startingPointCall = CALL_RECEIVE_REQUEST_SERVICE_CONTEXT;
  115. intermediatePointCall = CALL_RECEIVE_REQUEST;
  116. endingPointCall = CALL_SEND_REPLY;
  117. }
  118. /*
  119. **********************************************************************
  120. * Access protection
  121. **********************************************************************/
  122. // Method IDs for all methods in ServerRequestInfo. This allows for a
  123. // convenient O(1) lookup for checkAccess().
  124. protected static final int MID_SENDING_EXCEPTION = MID_RI_LAST + 1;
  125. protected static final int MID_OBJECT_ID = MID_RI_LAST + 2;
  126. protected static final int MID_ADAPTER_ID = MID_RI_LAST + 3;
  127. protected static final int MID_TARGET_MOST_DERIVED_INTERFACE
  128. = MID_RI_LAST + 4;
  129. protected static final int MID_GET_SERVER_POLICY = MID_RI_LAST + 5;
  130. protected static final int MID_SET_SLOT = MID_RI_LAST + 6;
  131. protected static final int MID_TARGET_IS_A = MID_RI_LAST + 7;
  132. protected static final int MID_ADD_REPLY_SERVICE_CONTEXT
  133. = MID_RI_LAST + 8;
  134. // ServerRequestInfo validity table (see ptc/00-08-06 table 21-2).
  135. // Note: These must be in the same order as specified in contants.
  136. protected static final boolean validCall[][] = {
  137. // LEGEND:
  138. // r_rsc = receive_request_service_contexts
  139. // r_req = receive_request
  140. // s_rep = send_reply
  141. // s_exc = send_exception
  142. // s_oth = send_other
  143. //
  144. // A true value indicates call is valid at specified point.
  145. // A false value indicates the call is invalid.
  146. //
  147. // NOTE: If the order or number of columns change, update
  148. // checkAccess() accordingly.
  149. //
  150. // { r_rsc, r_req, s_rep, s_exc, s_oth }
  151. // RequestInfo methods:
  152. /*request_id*/ { true , true , true , true , true },
  153. /*operation*/ { true , true , true , true , true },
  154. /*arguments*/ { false, true , true , false, false },
  155. /*exceptions*/ { false, true , true , true , true },
  156. /*contexts*/ { false, true , true , true , true },
  157. /*operation_context*/ { false, true , true , false, false },
  158. /*result*/ { false, false, true , false, false },
  159. /*response_expected*/ { true , true , true , true , true },
  160. /*sync_scope*/ { true , true , true , true , true },
  161. /*reply_status*/ { false, false, true , true , true },
  162. /*forward_reference*/ { false, false, false, false, true },
  163. /*get_slot*/ { true , true , true , true , true },
  164. /*get_request_service_context*/ { true , true , true , true , true },
  165. /*get_reply_service_context*/ { false, false, true , true , true },
  166. //
  167. // ServerRequestInfo methods::
  168. /*sending_exception*/ { false, false, false, true , false },
  169. /*object_id*/ { false, true , true , true , true },
  170. /*adapter_id*/ { false, true , true , true , true },
  171. /*target_most_derived_inte...*/ { false, true , false, false, false },
  172. /*get_server_policy*/ { true , true , true , true , true },
  173. /*set_slot*/ { true , true , true , true , true },
  174. /*target_is_a*/ { false, true , false, false, false },
  175. /*add_reply_service_context*/ { true , true , true , true , true }
  176. };
  177. /*
  178. **********************************************************************
  179. * Public interfaces
  180. **********************************************************************/
  181. /**
  182. * Creates a new ServerRequestInfo implementation.
  183. * The constructor is package scope since no other package need create
  184. * an instance of this class.
  185. */
  186. ServerRequestInfoImpl( PIORB piOrb ) {
  187. super( piOrb );
  188. startingPointCall = CALL_RECEIVE_REQUEST_SERVICE_CONTEXT;
  189. intermediatePointCall = CALL_RECEIVE_REQUEST;
  190. endingPointCall = CALL_SEND_REPLY;
  191. serverRequestId = piOrb.allocateServerRequestId();
  192. }
  193. /**
  194. * Any containing the exception to be returned to the client.
  195. */
  196. public Any sending_exception () {
  197. checkAccess( MID_SENDING_EXCEPTION );
  198. if( cachedSendingException == null ) {
  199. Any result;
  200. if( dsiException != null ) {
  201. result = dsiException;
  202. }
  203. else if( exception != null ) {
  204. result = exceptionToAny( exception );
  205. }
  206. else {
  207. // sending_exception should not be callable if both dsiException
  208. // and exception are null.
  209. throw new INTERNAL(
  210. "Exception not available in sending_exception.",
  211. MinorCodes.EXCEPTION_UNAVAILABLE,
  212. CompletionStatus.COMPLETED_NO );
  213. }
  214. cachedSendingException = result;
  215. }
  216. return cachedSendingException;
  217. }
  218. /**
  219. * The opaque object_id describing the target of the operation invocation.
  220. */
  221. public byte[] object_id () {
  222. checkAccess( MID_OBJECT_ID );
  223. if( objectId == null ) {
  224. // For some reason, we never set object id. This could be
  225. // because a servant locator caused a location forward or
  226. // raised an exception. As per ptc/00-08-06, section 21.3.14,
  227. // we throw NO_RESOURCES
  228. throw new NO_RESOURCES( "object id never set.",
  229. MinorCodes.PI_OPERATION_NOT_SUPPORTED,
  230. CompletionStatus.COMPLETED_NO );
  231. }
  232. // Good citizen: In the interest of efficiency, we will assume
  233. // interceptors will not change the resulting byte[] array.
  234. // Otherwise, we would need to make a clone of this array.
  235. return objectId;
  236. }
  237. /**
  238. * The opaque identifier for the object adapter.
  239. */
  240. public byte[] adapter_id () {
  241. checkAccess( MID_ADAPTER_ID );
  242. if( adapterId == null ) {
  243. // For some reason, we never set the adapter id. This could be
  244. // because a servant locator caused a location forward or
  245. // raised an exception. As per ptc/00-08-06, section 21.3.14,
  246. // we throw NO_RESOURCES
  247. throw new NO_RESOURCES( "adapter id never set.",
  248. MinorCodes.PI_OPERATION_NOT_SUPPORTED,
  249. CompletionStatus.COMPLETED_NO );
  250. }
  251. // Good citizen: In the interest of efficiency, we will assume
  252. // interceptors will not change the resulting byte[] array.
  253. // Otherwise, we would need to make a clone of this array.
  254. return adapterId;
  255. }
  256. /**
  257. * The RepositoryID for the most derived interface of the servant.
  258. */
  259. public String target_most_derived_interface () {
  260. checkAccess( MID_TARGET_MOST_DERIVED_INTERFACE );
  261. return targetMostDerivedInterface;
  262. }
  263. /**
  264. * Returns the policy in effect for this operation for the given policy
  265. * type.
  266. */
  267. public Policy get_server_policy (int type) {
  268. // access is currently valid for all states:
  269. //checkAccess( MID_GET_SERVER_POLICY );
  270. Policy result = null;
  271. if( poaimpl != null ) {
  272. result = poaimpl.get_effective_policy( type );
  273. }
  274. // _REVISIT_ RTF Issue: get_server_policy spec not in sync with
  275. // get_effective_policy spec.
  276. return result;
  277. }
  278. /**
  279. * Allows an Interceptor to set a slot in the Current that is in the scope
  280. * of the request. If data already exists in that slot, it will be
  281. * overwritten. If the ID does not define an allocated slot, InvalidSlot
  282. * is raised.
  283. */
  284. public void set_slot (int id, Any data) throws InvalidSlot {
  285. // access is currently valid for all states:
  286. //checkAccess( MID_SET_SLOT );
  287. slotTable.set_slot( id, data );
  288. }
  289. /**
  290. * Returns true if the servant is the given RepositoryId, false if it is
  291. * not.
  292. */
  293. public boolean target_is_a (String id) {
  294. checkAccess( MID_TARGET_IS_A );
  295. boolean result;
  296. if( servant instanceof Servant ) {
  297. result = ((Servant)servant)._is_a( id );
  298. }
  299. else if( servant instanceof ObjectImpl ) {
  300. result = ((ObjectImpl)servant)._is_a( id );
  301. }
  302. else {
  303. throw new INTERNAL(
  304. "During target_is_a, servant was not a Servant or ObjectImpl",
  305. MinorCodes.SERVANT_INVALID,
  306. CompletionStatus.COMPLETED_NO );
  307. }
  308. return result;
  309. }
  310. /**
  311. * Allows Interceptors to add service contexts to the request.
  312. */
  313. public void add_reply_service_context ( ServiceContext service_context,
  314. boolean replace )
  315. {
  316. // access is currently valid for all states:
  317. //checkAccess( MID_ADD_REPLY_SERVICE_CONTEXT );
  318. if( currentExecutionPoint == EXECUTION_POINT_ENDING ) {
  319. ServiceContexts scs = replyMessage.getServiceContexts();
  320. // May be null. If this is null, create a new one in its place.
  321. if( scs == null ) {
  322. scs = new ServiceContexts( piOrb );
  323. replyMessage.setServiceContexts( scs );
  324. }
  325. if( cachedReplyServiceContexts == null ) {
  326. cachedReplyServiceContexts = new HashMap();
  327. }
  328. // This is during and ending point, so we now have enough
  329. // information to add the reply service context.
  330. addServiceContext( cachedReplyServiceContexts, scs,
  331. service_context, replace );
  332. }
  333. // We enqueue all adds for the following reasons:
  334. //
  335. // If we are not in the ending point then we do not yet have a
  336. // pointer to the ServiceContexts object so we cannot access the
  337. // service contexts until we get to the ending point.
  338. // So we enqueue this add reply service context request.
  339. // It is added when we do have a handle on the service contexts object.
  340. //
  341. // If we are in the ending point and we just add directly to the
  342. // SC container but then an interceptor raises a SystemException
  343. // then that add will be lost since a new container is created
  344. // for the SystemException response.
  345. //
  346. // Therefore we always enqueue and never dequeue (per request) so
  347. // that all adds will be completed.
  348. AddReplyServiceContextCommand addReply =
  349. new AddReplyServiceContextCommand();
  350. addReply.service_context = service_context;
  351. addReply.replace = replace;
  352. if( addReplyServiceContextQueue == null ) {
  353. addReplyServiceContextQueue = new ArrayList();
  354. }
  355. // REVISIT: this does not add to the cache.
  356. enqueue( addReply );
  357. }
  358. // NOTE: When adding a method, be sure to:
  359. // 1. Add a MID_* constant for that method
  360. // 2. Call checkAccess at the start of the method
  361. // 3. Define entries in the validCall[][] table for interception points.
  362. /*
  363. **********************************************************************
  364. * Public RequestInfo interfaces
  365. *
  366. * These are implemented here because they have differing
  367. * implementations depending on whether this is a client or a server
  368. * request info object.
  369. **********************************************************************/
  370. /**
  371. * See ServerRequestInfo for javadocs.
  372. */
  373. public int request_id (){
  374. // access is currently valid for all states:
  375. //checkAccess( MID_REQUEST_ID );
  376. /*
  377. * NOTE: The request id in server interceptors is NOT the
  378. * same as the GIOP request id. The ORB may be servicing several
  379. * connections, each with possibly overlapping sets of request ids.
  380. * Therefore we create a request id specific to interceptors.
  381. */
  382. return serverRequestId;
  383. }
  384. /**
  385. * See ServerRequestInfo for javadocs.
  386. */
  387. public String operation (){
  388. // access is currently valid for all states:
  389. //checkAccess( MID_OPERATION );
  390. return request.getOperationName();
  391. }
  392. /**
  393. * See ServerRequestInfo for javadocs.
  394. */
  395. public Parameter[] arguments (){
  396. checkAccess( MID_ARGUMENTS );
  397. if( cachedArguments == null ) {
  398. if( !isDynamic ) {
  399. throw new NO_RESOURCES(
  400. "The Portable Java Bindings do not support arguments()",
  401. MinorCodes.PI_OPERATION_NOT_SUPPORTED,
  402. CompletionStatus.COMPLETED_NO );
  403. }
  404. if( dsiArguments == null ) {
  405. throw new NO_RESOURCES(
  406. "ServerRequest::arguments() never called.",
  407. MinorCodes.PI_OPERATION_NOT_SUPPORTED,
  408. CompletionStatus.COMPLETED_NO );
  409. }
  410. // If it is a DSI request then get the arguments from the DSI req
  411. // and convert that into parameters.
  412. cachedArguments = nvListToParameterArray( dsiArguments );
  413. }
  414. // Good citizen: In the interest of efficiency, we assume
  415. // interceptors will be "good citizens" in that they will not
  416. // modify the contents of the Parameter[] array. We also assume
  417. // they will not change the values of the containing Anys.
  418. return cachedArguments;
  419. }
  420. /**
  421. * See ServerRequestInfo for javadocs.
  422. */
  423. public TypeCode[] exceptions (){
  424. checkAccess( MID_EXCEPTIONS );
  425. // _REVISIT_ PI RTF Issue: No exception list on server side.
  426. throw new NO_RESOURCES(
  427. "The Portable Java Bindings do not support exceptions()",
  428. MinorCodes.PI_OPERATION_NOT_SUPPORTED,
  429. CompletionStatus.COMPLETED_NO );
  430. }
  431. /**
  432. * See ServerRequestInfo for javadocs.
  433. */
  434. public String[] contexts (){
  435. checkAccess( MID_CONTEXTS );
  436. // We do not support this because our ORB does not send contexts.
  437. throw new NO_RESOURCES(
  438. "The Portable Java Bindings do not support contexts()",
  439. MinorCodes.PI_OPERATION_NOT_SUPPORTED,
  440. CompletionStatus.COMPLETED_NO );
  441. }
  442. /**
  443. * See ServerRequestInfo for javadocs.
  444. */
  445. public String[] operation_context (){
  446. checkAccess( MID_OPERATION_CONTEXT );
  447. // We do not support this because our ORB does not send
  448. // operation_context.
  449. throw new NO_RESOURCES(
  450. "The Portable Java Bindings do not support operation_context()",
  451. MinorCodes.PI_OPERATION_NOT_SUPPORTED,
  452. CompletionStatus.COMPLETED_NO );
  453. }
  454. /**
  455. * See ServerRequestInfo for javadocs.
  456. */
  457. public Any result (){
  458. checkAccess( MID_RESULT );
  459. if( !isDynamic ) {
  460. throw new NO_RESOURCES(
  461. "The Portable Java Bindings do not support result()",
  462. MinorCodes.PI_OPERATION_NOT_SUPPORTED,
  463. CompletionStatus.COMPLETED_NO );
  464. }
  465. if( dsiResult == null ) {
  466. throw new INTERNAL(
  467. "dsiResult should not be null.",
  468. MinorCodes.PI_DSI_RESULT_IS_NULL,
  469. CompletionStatus.COMPLETED_NO );
  470. }
  471. // Good citizen: In the interest of efficiency, we assume that
  472. // interceptors will not modify the contents of the result Any.
  473. // Otherwise, we would need to create a deep copy of the Any.
  474. return dsiResult;
  475. }
  476. /**
  477. * See ServerRequestInfo for javadocs.
  478. */
  479. public boolean response_expected (){
  480. // access is currently valid for all states:
  481. //checkAccess( MID_RESPONSE_EXPECTED );
  482. return !request.isOneWay();
  483. }
  484. /**
  485. * See ServerRequestInfo for javadocs.
  486. */
  487. public Object forward_reference (){
  488. checkAccess( MID_FORWARD_REFERENCE );
  489. // Check to make sure we are in LOCATION_FORWARD
  490. // state as per ptc/00-08-06, table 21-2
  491. // footnote 2.
  492. if( replyStatus != LOCATION_FORWARD.value ) {
  493. throw new BAD_INV_ORDER(
  494. "Invalid to query forward_reference() when reply status " +
  495. "is not LOCATION_FORWARD.",
  496. MinorCodes.INVALID_PI_CALL, CompletionStatus.COMPLETED_NO );
  497. }
  498. return getForwardRequestException().forward;
  499. }
  500. /**
  501. * See ServerRequestInfo for javadocs.
  502. */
  503. public org.omg.IOP.ServiceContext get_request_service_context( int id ) {
  504. checkAccess( MID_GET_REQUEST_SERVICE_CONTEXT );
  505. if( cachedRequestServiceContexts == null ) {
  506. cachedRequestServiceContexts = new HashMap();
  507. }
  508. return getServiceContext( cachedRequestServiceContexts,
  509. request.getServiceContexts(), id );
  510. }
  511. /**
  512. * See ServerRequestInfo for javadocs.
  513. */
  514. public org.omg.IOP.ServiceContext get_reply_service_context( int id ) {
  515. checkAccess( MID_GET_REPLY_SERVICE_CONTEXT );
  516. if( cachedReplyServiceContexts == null ) {
  517. cachedReplyServiceContexts = new HashMap();
  518. }
  519. return getServiceContext( cachedReplyServiceContexts,
  520. replyMessage.getServiceContexts(), id );
  521. }
  522. /*
  523. **********************************************************************
  524. * Private-scope classes and methods
  525. **********************************************************************/
  526. // A command encapsulating a request to add a reply service context.
  527. // These commands are enqueued until we have a handle on the actual
  528. // reply service context, at which point they are executed.
  529. private class AddReplyServiceContextCommand {
  530. ServiceContext service_context;
  531. boolean replace;
  532. }
  533. // Adds the given add reply service context command to the queue of
  534. // such commands. If a command is detected to have the same id as
  535. // the service context in this command, and replace is false,
  536. // BAD_INV_ORDER is thrown. If replace is true, the original command
  537. // in the queue is replaced by this command.
  538. private void enqueue( AddReplyServiceContextCommand addReply ) {
  539. int size = addReplyServiceContextQueue.size();
  540. boolean found = false;
  541. for( int i = 0; i < size; i++ ) {
  542. AddReplyServiceContextCommand cmd =
  543. (AddReplyServiceContextCommand)
  544. addReplyServiceContextQueue.get( i );
  545. if( cmd.service_context.context_id ==
  546. addReply.service_context.context_id )
  547. {
  548. found = true;
  549. if( addReply.replace ) {
  550. addReplyServiceContextQueue.set( i, addReply );
  551. }
  552. else {
  553. throw new BAD_INV_ORDER(
  554. "Service context already exists with the given ID " +
  555. "and replace flag not set.",
  556. MinorCodes.SERVICE_CONTEXT_ADD_FAILED,
  557. CompletionStatus.COMPLETED_NO );
  558. }
  559. break;
  560. }
  561. }
  562. if( !found ) {
  563. addReplyServiceContextQueue.add( addReply );
  564. }
  565. }
  566. /*
  567. **********************************************************************
  568. * Package and protected-scope methods
  569. **********************************************************************/
  570. /**
  571. * Overridden from RequestInfoImpl. This version calls the super
  572. * and then, if we are changing to ending points, executes all
  573. * enqueued AddReplyServiceContextCommands.
  574. */
  575. protected void setCurrentExecutionPoint( int executionPoint ) {
  576. super.setCurrentExecutionPoint( executionPoint );
  577. // If we are transitioning to ending point, we will now have a pointer
  578. // to the reply service contexts, so we can execute all queued
  579. // add reply service context requests.
  580. if( (executionPoint == EXECUTION_POINT_ENDING) &&
  581. (addReplyServiceContextQueue != null) )
  582. {
  583. int size = addReplyServiceContextQueue.size();
  584. for( int i = 0; i < size; i++ ) {
  585. AddReplyServiceContextCommand addReply =
  586. (AddReplyServiceContextCommand)
  587. addReplyServiceContextQueue.get( i );
  588. try {
  589. add_reply_service_context( addReply.service_context,
  590. addReply.replace );
  591. }
  592. catch( BAD_INV_ORDER e ) {
  593. // _REVISIT_ The only way this can happen is if during
  594. // rrsc or rr, the interceptor tried to add with
  595. // replace=false to a service context that is present in
  596. // the reply message. At that time there was no way for
  597. // us to check for this, so the best we can do is ignore
  598. // the original request.
  599. }
  600. }
  601. // We specifically do not empty the SC queue so that if
  602. // the interceptor raises an exception the queued service contexts
  603. // will be put in the exception response.
  604. }
  605. }
  606. /**
  607. * Stores the various sources of information used for this info object.
  608. */
  609. protected void setInfo( ServerRequest request, POAImpl poaimpl,
  610. byte[] objectId, byte[] adapterId )
  611. {
  612. this.request = request;
  613. this.objectId = objectId;
  614. this.adapterId = adapterId;
  615. this.poaimpl = poaimpl;
  616. this.connection =
  617. ((com.sun.corba.se.internal.iiop.IIOPInputStream)request)
  618. .getConnection();
  619. }
  620. /**
  621. * Stores the various sources of information used for this info object.
  622. */
  623. protected void setDSIArguments( NVList arguments ) {
  624. this.dsiArguments = arguments;
  625. }
  626. /**
  627. * Stores the various sources of information used for this info object.
  628. */
  629. protected void setDSIException( Any exception ) {
  630. this.dsiException = exception;
  631. // Clear cached exception value:
  632. cachedSendingException = null;
  633. }
  634. /**
  635. * Stores the various sources of information used for this info object.
  636. */
  637. protected void setDSIResult( Any result ) {
  638. this.dsiResult = result;
  639. }
  640. /**
  641. * Sets the exception to be returned by received_exception and
  642. * received_exception_id.
  643. */
  644. protected void setException( Exception exception ) {
  645. super.setException( exception );
  646. // Make sure DSIException is null because this is the more recent one.
  647. this.dsiException = null;
  648. // Clear cached exception value:
  649. cachedSendingException = null;
  650. }
  651. /**
  652. * Stores the various sources of information used for this info object.
  653. */
  654. protected void setInfo( java.lang.Object servant,
  655. String targetMostDerivedInterface )
  656. {
  657. this.servant = servant;
  658. this.targetMostDerivedInterface = targetMostDerivedInterface;
  659. this.isDynamic =
  660. (servant instanceof
  661. org.omg.PortableServer.DynamicImplementation) ||
  662. (servant instanceof org.omg.CORBA.DynamicImplementation);
  663. }
  664. /**
  665. * Set reply message
  666. */
  667. void setReplyMessage( ReplyMessage replyMessage ) {
  668. this.replyMessage = replyMessage;
  669. }
  670. /**
  671. * Overridden from RequestInfoImpl. Calls the super class, then
  672. * sets the ending point call depending on the reply status.
  673. */
  674. protected void setReplyStatus( short replyStatus ) {
  675. super.setReplyStatus( replyStatus );
  676. switch( replyStatus ) {
  677. case SUCCESSFUL.value:
  678. endingPointCall = CALL_SEND_REPLY;
  679. break;
  680. case SYSTEM_EXCEPTION.value:
  681. case USER_EXCEPTION.value:
  682. endingPointCall = CALL_SEND_EXCEPTION;
  683. break;
  684. case LOCATION_FORWARD.value:
  685. case TRANSPORT_RETRY.value:
  686. endingPointCall = CALL_SEND_OTHER;
  687. break;
  688. }
  689. }
  690. /**
  691. * Release the servant object so the user has control over its lifetime.
  692. * Called after receive_request is finished executing.
  693. */
  694. void releaseServant() {
  695. this.servant = null;
  696. }
  697. /**
  698. * Sets the forwardRequestRaisedInEnding flag to true, indicating that
  699. * a server ending point has raised location forward at some point.
  700. */
  701. void setForwardRequestRaisedInEnding() {
  702. this.forwardRequestRaisedInEnding = true;
  703. }
  704. /**
  705. * Returns true if ForwardRequest was raised by a server ending point
  706. * or false otherwise.
  707. */
  708. boolean isForwardRequestRaisedInEnding() {
  709. return this.forwardRequestRaisedInEnding;
  710. }
  711. /**
  712. * Returns true if this is a dynamic invocation, or false if not
  713. */
  714. boolean isDynamic() {
  715. return this.isDynamic;
  716. }
  717. /**
  718. * See description for RequestInfoImpl.checkAccess
  719. */
  720. protected void checkAccess( int methodID )
  721. throws BAD_INV_ORDER
  722. {
  723. // Make sure currentPoint matches the appropriate index in the
  724. // validCall table:
  725. int validCallIndex = 0;
  726. switch( currentExecutionPoint ) {
  727. case EXECUTION_POINT_STARTING:
  728. validCallIndex = 0;
  729. break;
  730. case EXECUTION_POINT_INTERMEDIATE:
  731. validCallIndex = 1;
  732. break;
  733. case EXECUTION_POINT_ENDING:
  734. switch( endingPointCall ) {
  735. case CALL_SEND_REPLY:
  736. validCallIndex = 2;
  737. break;
  738. case CALL_SEND_EXCEPTION:
  739. validCallIndex = 3;
  740. break;
  741. case CALL_SEND_OTHER:
  742. validCallIndex = 4;
  743. break;
  744. }
  745. break;
  746. }
  747. // Check the validCall table:
  748. if( !validCall[methodID][validCallIndex] ) {
  749. throw new BAD_INV_ORDER(
  750. "Cannot access this info attribute/method at this point.",
  751. MinorCodes.INVALID_PI_CALL, CompletionStatus.COMPLETED_NO );
  752. }
  753. }
  754. }