1. /*
  2. * @(#)ClientRequestInfoImpl.java 1.45 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.HashMap ;
  9. import org.omg.CORBA.Any;
  10. import org.omg.CORBA.BAD_INV_ORDER;
  11. import org.omg.CORBA.BAD_PARAM;
  12. import org.omg.CORBA.CompletionStatus;
  13. import org.omg.CORBA.Context;
  14. import org.omg.CORBA.ContextList;
  15. import org.omg.CORBA.CTX_RESTRICT_SCOPE;
  16. import org.omg.CORBA.ExceptionList;
  17. import org.omg.CORBA.LocalObject;
  18. import org.omg.CORBA.NamedValue;
  19. import org.omg.CORBA.NO_IMPLEMENT;
  20. import org.omg.CORBA.NO_RESOURCES;
  21. import org.omg.CORBA.NVList;
  22. import org.omg.CORBA.Object;
  23. import org.omg.CORBA.ParameterMode;
  24. import org.omg.CORBA.Policy;
  25. import org.omg.CORBA.SystemException;
  26. import org.omg.CORBA.TypeCode;
  27. import org.omg.CORBA.INTERNAL;
  28. import org.omg.CORBA.UserException;
  29. import org.omg.CORBA.portable.ApplicationException;
  30. import org.omg.CORBA.portable.InputStream;
  31. import com.sun.corba.se.spi.servicecontext.ServiceContexts;
  32. import com.sun.corba.se.spi.servicecontext.UnknownServiceContext;
  33. import org.omg.IOP.ServiceContext;
  34. import org.omg.IOP.ServiceContextHelper;
  35. import org.omg.IOP.TaggedProfile;
  36. import org.omg.IOP.TaggedProfileHelper;
  37. import org.omg.IOP.TaggedComponent;
  38. import org.omg.IOP.TaggedComponentHelper;
  39. import org.omg.IOP.TAG_INTERNET_IOP;
  40. import org.omg.Dynamic.Parameter;
  41. import org.omg.PortableInterceptor.ClientRequestInfo;
  42. import org.omg.PortableInterceptor.LOCATION_FORWARD;
  43. import org.omg.PortableInterceptor.SUCCESSFUL;
  44. import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;
  45. import org.omg.PortableInterceptor.TRANSPORT_RETRY;
  46. import org.omg.PortableInterceptor.USER_EXCEPTION;
  47. import com.sun.corba.se.pept.protocol.MessageMediator;
  48. import com.sun.corba.se.spi.ior.IOR;
  49. import com.sun.corba.se.spi.ior.iiop.IIOPProfileTemplate;
  50. import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
  51. import com.sun.corba.se.spi.orb.ORB;
  52. import com.sun.corba.se.spi.protocol.CorbaMessageMediator;
  53. import com.sun.corba.se.spi.transport.CorbaContactInfo;
  54. import com.sun.corba.se.spi.transport.CorbaContactInfoList;
  55. import com.sun.corba.se.spi.transport.CorbaContactInfoListIterator;
  56. import com.sun.corba.se.impl.encoding.CDROutputStream;
  57. import com.sun.corba.se.impl.encoding.CDRInputStream_1_0;
  58. import com.sun.corba.se.impl.orbutil.ORBUtility;
  59. import com.sun.corba.se.impl.protocol.CorbaInvocationInfo;
  60. import com.sun.corba.se.impl.util.RepositoryId;
  61. /**
  62. * Implementation of the ClientRequestInfo interface as specified in
  63. * orbos/99-12-02 section 5.4.2.
  64. */
  65. public final class ClientRequestInfoImpl
  66. extends RequestInfoImpl
  67. implements ClientRequestInfo
  68. {
  69. // The available constants for startingPointCall
  70. static final int CALL_SEND_REQUEST = 0;
  71. static final int CALL_SEND_POLL = 1;
  72. // The available constants for endingPointCall
  73. static final int CALL_RECEIVE_REPLY = 0;
  74. static final int CALL_RECEIVE_EXCEPTION = 1;
  75. static final int CALL_RECEIVE_OTHER = 2;
  76. //////////////////////////////////////////////////////////////////////
  77. //
  78. // NOTE: IF AN ATTRIBUTE IS ADDED, PLEASE UPDATE RESET();
  79. //
  80. //////////////////////////////////////////////////////////////////////
  81. // The current retry request status. True if this request is being
  82. // retried and this info object is to be reused, or false otherwise.
  83. private boolean retryRequest;
  84. // The number of times this info object has been (re)used. This is
  85. // incremented every time a request is retried, and decremented every
  86. // time a request is complete. When this reaches zero, the info object
  87. // is popped from the ClientRequestInfoImpl ThreadLocal stack in the ORB.
  88. private int entryCount = 0;
  89. // The RequestImpl is set when the call is DII based.
  90. // The DII query calls like ParameterList, ExceptionList,
  91. // ContextList will be delegated to RequestImpl.
  92. private org.omg.CORBA.Request request;
  93. // Sources of client request information
  94. private boolean diiInitiate;
  95. private CorbaMessageMediator messageMediator;
  96. // Cached information:
  97. private org.omg.CORBA.Object cachedTargetObject;
  98. private org.omg.CORBA.Object cachedEffectiveTargetObject;
  99. private Parameter[] cachedArguments;
  100. private TypeCode[] cachedExceptions;
  101. private String[] cachedContexts;
  102. private String[] cachedOperationContext;
  103. private String cachedReceivedExceptionId;
  104. private Any cachedResult;
  105. private Any cachedReceivedException;
  106. private TaggedProfile cachedEffectiveProfile;
  107. // key = Integer, value = IOP.ServiceContext.
  108. private HashMap cachedRequestServiceContexts;
  109. // key = Integer, value = IOP.ServiceContext.
  110. private HashMap cachedReplyServiceContexts;
  111. // key = Integer, value = TaggedComponent
  112. private HashMap cachedEffectiveComponents;
  113. protected boolean piCurrentPushed;
  114. //////////////////////////////////////////////////////////////////////
  115. //
  116. // NOTE: IF AN ATTRIBUTE IS ADDED, PLEASE UPDATE RESET();
  117. //
  118. //////////////////////////////////////////////////////////////////////
  119. /**
  120. * Reset the info object so that it can be reused for a retry,
  121. * for example.
  122. */
  123. void reset() {
  124. super.reset();
  125. // Please keep these in the same order that they're declared above.
  126. retryRequest = false;
  127. // Do not reset entryCount because we need to know when to pop this
  128. // from the stack.
  129. request = null;
  130. diiInitiate = false;
  131. messageMediator = null;
  132. // Clear cached attributes:
  133. cachedTargetObject = null;
  134. cachedEffectiveTargetObject = null;
  135. cachedArguments = null;
  136. cachedExceptions = null;
  137. cachedContexts = null;
  138. cachedOperationContext = null;
  139. cachedReceivedExceptionId = null;
  140. cachedResult = null;
  141. cachedReceivedException = null;
  142. cachedEffectiveProfile = null;
  143. cachedRequestServiceContexts = null;
  144. cachedReplyServiceContexts = null;
  145. cachedEffectiveComponents = null;
  146. piCurrentPushed = false;
  147. startingPointCall = CALL_SEND_REQUEST;
  148. endingPointCall = CALL_RECEIVE_REPLY;
  149. }
  150. /*
  151. **********************************************************************
  152. * Access protection
  153. **********************************************************************/
  154. // Method IDs for all methods in ClientRequestInfo. This allows for a
  155. // convenient O(1) lookup for checkAccess().
  156. protected static final int MID_TARGET = MID_RI_LAST + 1;
  157. protected static final int MID_EFFECTIVE_TARGET = MID_RI_LAST + 2;
  158. protected static final int MID_EFFECTIVE_PROFILE = MID_RI_LAST + 3;
  159. protected static final int MID_RECEIVED_EXCEPTION = MID_RI_LAST + 4;
  160. protected static final int MID_RECEIVED_EXCEPTION_ID = MID_RI_LAST + 5;
  161. protected static final int MID_GET_EFFECTIVE_COMPONENT = MID_RI_LAST + 6;
  162. protected static final int MID_GET_EFFECTIVE_COMPONENTS
  163. = MID_RI_LAST + 7;
  164. protected static final int MID_GET_REQUEST_POLICY = MID_RI_LAST + 8;
  165. protected static final int MID_ADD_REQUEST_SERVICE_CONTEXT
  166. = MID_RI_LAST + 9;
  167. // ClientRequestInfo validity table (see ptc/00-08-06 table 21-1).
  168. // Note: These must be in the same order as specified in contants.
  169. protected static final boolean validCall[][] = {
  170. // LEGEND:
  171. // s_req = send_request r_rep = receive_reply
  172. // s_pol = send_poll r_exc = receive_exception
  173. // r_oth = receive_other
  174. //
  175. // A true value indicates call is valid at specified point.
  176. // A false value indicates the call is invalid.
  177. //
  178. //
  179. // NOTE: If the order or number of columns change, update
  180. // checkAccess() accordingly.
  181. //
  182. // { s_req, s_pol, r_rep, r_exc, r_oth }
  183. // RequestInfo methods:
  184. /*request_id*/ { true , true , true , true , true },
  185. /*operation*/ { true , true , true , true , true },
  186. /*arguments*/ { true , false, true , false, false },
  187. /*exceptions*/ { true , false, true , true , true },
  188. /*contexts*/ { true , false, true , true , true },
  189. /*operation_context*/ { true , false, true , true , true },
  190. /*result*/ { false, false, true , false, false },
  191. /*response_expected*/ { true , true , true , true , true },
  192. /*sync_scope*/ { true , false, true , true , true },
  193. /*reply_status*/ { false, false, true , true , true },
  194. /*forward_reference*/ { false, false, false, false, true },
  195. /*get_slot*/ { true , true , true , true , true },
  196. /*get_request_service_context*/ { true , false, true , true , true },
  197. /*get_reply_service_context*/ { false, false, true , true , true },
  198. //
  199. // ClientRequestInfo methods::
  200. /*target*/ { true , true , true , true , true },
  201. /*effective_target*/ { true , true , true , true , true },
  202. /*effective_profile*/ { true , true , true , true , true },
  203. /*received_exception*/ { false, false, false, true , false },
  204. /*received_exception_id*/ { false, false, false, true , false },
  205. /*get_effective_component*/ { true , false, true , true , true },
  206. /*get_effective_components*/ { true , false, true , true , true },
  207. /*get_request_policy*/ { true , false, true , true , true },
  208. /*add_request_service_context*/ { true , false, false, false, false }
  209. };
  210. /*
  211. **********************************************************************
  212. * Public ClientRequestInfo interfaces
  213. **********************************************************************/
  214. /**
  215. * Creates a new ClientRequestInfo implementation.
  216. * The constructor is package scope since no other package need create
  217. * an instance of this class.
  218. */
  219. protected ClientRequestInfoImpl( ORB myORB ) {
  220. super( myORB );
  221. startingPointCall = CALL_SEND_REQUEST;
  222. endingPointCall = CALL_RECEIVE_REPLY;
  223. }
  224. /**
  225. * The object which the client called to perform the operation.
  226. */
  227. public org.omg.CORBA.Object target (){
  228. // access is currently valid for all states:
  229. //checkAccess( MID_TARGET );
  230. if (cachedTargetObject == null) {
  231. CorbaContactInfo corbaContactInfo = (CorbaContactInfo)
  232. messageMediator.getContactInfo();
  233. cachedTargetObject =
  234. iorToObject(corbaContactInfo.getTargetIOR());
  235. }
  236. return cachedTargetObject;
  237. }
  238. /**
  239. * The actual object on which the operation will be invoked. If the
  240. * reply_status is LOCATION_FORWARD, then on subsequent requests,
  241. * effective_target will contain the forwarded IOR while target will
  242. * remain unchanged.
  243. */
  244. public org.omg.CORBA.Object effective_target() {
  245. // access is currently valid for all states:
  246. //checkAccess( MID_EFFECTIVE_TARGET );
  247. // Note: This is not necessarily the same as locatedIOR.
  248. // Reason: See the way we handle COMM_FAILURES in
  249. // ClientRequestDispatcher.createRequest, v1.32
  250. if (cachedEffectiveTargetObject == null) {
  251. CorbaContactInfo corbaContactInfo = (CorbaContactInfo)
  252. messageMediator.getContactInfo();
  253. // REVISIT - get through chain like getLocatedIOR helper below.
  254. cachedEffectiveTargetObject =
  255. iorToObject(corbaContactInfo.getEffectiveTargetIOR());
  256. }
  257. return cachedEffectiveTargetObject;
  258. }
  259. /**
  260. * The profile that will be used to send the request. If a location
  261. * forward has occurred for this operation's object and that object's
  262. * profile change accordingly, then this profile will be that located
  263. * profile.
  264. */
  265. public TaggedProfile effective_profile (){
  266. // access is currently valid for all states:
  267. //checkAccess( MID_EFFECTIVE_PROFILE );
  268. if( cachedEffectiveProfile == null ) {
  269. CorbaContactInfo corbaContactInfo = (CorbaContactInfo)
  270. messageMediator.getContactInfo();
  271. cachedEffectiveProfile =
  272. corbaContactInfo.getEffectiveProfile().getIOPProfile();
  273. }
  274. // Good citizen: In the interest of efficiency, we assume interceptors
  275. // will not modify the returned TaggedProfile in any way so we need
  276. // not make a deep copy of it.
  277. return cachedEffectiveProfile;
  278. }
  279. /**
  280. * Contains the exception to be returned to the client.
  281. */
  282. public Any received_exception (){
  283. checkAccess( MID_RECEIVED_EXCEPTION );
  284. if( cachedReceivedException == null ) {
  285. cachedReceivedException = exceptionToAny( exception );
  286. }
  287. // Good citizen: In the interest of efficiency, we assume interceptors
  288. // will not modify the returned Any in any way so we need
  289. // not make a deep copy of it.
  290. return cachedReceivedException;
  291. }
  292. /**
  293. * The CORBA::RepositoryId of the exception to be returned to the client.
  294. */
  295. public String received_exception_id (){
  296. checkAccess( MID_RECEIVED_EXCEPTION_ID );
  297. if( cachedReceivedExceptionId == null ) {
  298. String result = null;
  299. if( exception == null ) {
  300. // Note: exception should never be null here since we will
  301. // throw a BAD_INV_ORDER if this is not called from
  302. // receive_exception.
  303. throw wrapper.exceptionWasNull() ;
  304. } else if( exception instanceof SystemException ) {
  305. String name = exception.getClass().getName();
  306. result = ORBUtility.repositoryIdOf(name);
  307. } else if( exception instanceof ApplicationException ) {
  308. result = ((ApplicationException)exception).getId();
  309. }
  310. // _REVISIT_ We need to be able to handle a UserException in the
  311. // DII case. How do we extract the ID from a UserException?
  312. cachedReceivedExceptionId = result;
  313. }
  314. return cachedReceivedExceptionId;
  315. }
  316. /**
  317. * Returns the IOP::TaggedComponent with the given ID from the profile
  318. * selected for this request. IF there is more than one component for a
  319. * given component ID, it is undefined which component this operation
  320. * returns (get_effective_component should be called instead).
  321. */
  322. public TaggedComponent get_effective_component (int id){
  323. checkAccess( MID_GET_EFFECTIVE_COMPONENT );
  324. return get_effective_components( id )[0];
  325. }
  326. /**
  327. * Returns all the tagged components with the given ID from the profile
  328. * selected for this request.
  329. */
  330. public TaggedComponent[] get_effective_components (int id){
  331. checkAccess( MID_GET_EFFECTIVE_COMPONENTS );
  332. Integer integerId = new Integer( id );
  333. TaggedComponent[] result = null;
  334. boolean justCreatedCache = false;
  335. if( cachedEffectiveComponents == null ) {
  336. cachedEffectiveComponents = new HashMap();
  337. justCreatedCache = true;
  338. }
  339. else {
  340. // Look in cache:
  341. result = (TaggedComponent[])cachedEffectiveComponents.get(
  342. integerId );
  343. }
  344. // null could mean we cached null or not in cache.
  345. if( (result == null) &&
  346. (justCreatedCache ||
  347. !cachedEffectiveComponents.containsKey( integerId ) ) )
  348. {
  349. // Not in cache. Get it from the profile:
  350. CorbaContactInfo corbaContactInfo = (CorbaContactInfo)
  351. messageMediator.getContactInfo();
  352. IIOPProfileTemplate ptemp =
  353. (IIOPProfileTemplate)corbaContactInfo.getEffectiveProfile().
  354. getTaggedProfileTemplate();
  355. result = ptemp.getIOPComponents(myORB, id);
  356. cachedEffectiveComponents.put( integerId, result );
  357. }
  358. // As per ptc/00-08-06, section 21.3.13.6., If not found, raise
  359. // BAD_PARAM with minor code INVALID_COMPONENT_ID.
  360. if( (result == null) || (result.length == 0) ) {
  361. throw stdWrapper.invalidComponentId( integerId ) ;
  362. }
  363. // Good citizen: In the interest of efficiency, we will assume
  364. // interceptors will not modify the returned TaggedCompoent[], or
  365. // the TaggedComponents inside of it. Otherwise, we would need to
  366. // clone the array and make a deep copy of its contents.
  367. return result;
  368. }
  369. /**
  370. * Returns the given policy in effect for this operation.
  371. */
  372. public Policy get_request_policy (int type){
  373. checkAccess( MID_GET_REQUEST_POLICY );
  374. // _REVISIT_ Our ORB is not policy-based at this time.
  375. throw wrapper.piOrbNotPolicyBased() ;
  376. }
  377. /**
  378. * Allows interceptors to add service contexts to the request.
  379. * <p>
  380. * There is no declaration of the order of the service contexts. They
  381. * may or may not appear in the order they are added.
  382. */
  383. public void add_request_service_context (ServiceContext service_context,
  384. boolean replace)
  385. {
  386. checkAccess( MID_ADD_REQUEST_SERVICE_CONTEXT );
  387. if( cachedRequestServiceContexts == null ) {
  388. cachedRequestServiceContexts = new HashMap();
  389. }
  390. addServiceContext( cachedRequestServiceContexts,
  391. messageMediator.getRequestServiceContexts(),
  392. service_context, replace );
  393. }
  394. // NOTE: When adding a method, be sure to:
  395. // 1. Add a MID_* constant for that method
  396. // 2. Call checkAccess at the start of the method
  397. // 3. Define entries in the validCall[][] table for interception points.
  398. /*
  399. **********************************************************************
  400. * Public RequestInfo interfaces
  401. *
  402. * These are implemented here because they have differing
  403. * implementations depending on whether this is a client or a server
  404. * request info object.
  405. **********************************************************************/
  406. /**
  407. * See RequestInfoImpl for javadoc.
  408. */
  409. public int request_id (){
  410. // access is currently valid for all states:
  411. //checkAccess( MID_REQUEST_ID );
  412. /*
  413. * NOTE: The requestId in client interceptors is the same as the
  414. * GIOP request id. This works because both interceptors and
  415. * request ids are scoped by the ORB on the client side.
  416. */
  417. return messageMediator.getRequestId();
  418. }
  419. /**
  420. * See RequestInfoImpl for javadoc.
  421. */
  422. public String operation (){
  423. // access is currently valid for all states:
  424. //checkAccess( MID_OPERATION );
  425. return messageMediator.getOperationName();
  426. }
  427. /**
  428. * See RequestInfoImpl for javadoc.
  429. */
  430. public Parameter[] arguments (){
  431. checkAccess( MID_ARGUMENTS );
  432. if( cachedArguments == null ) {
  433. if( request == null ) {
  434. throw stdWrapper.piOperationNotSupported1() ;
  435. }
  436. // If it is DII request then get the arguments from the DII req
  437. // and convert that into parameters.
  438. cachedArguments = nvListToParameterArray( request.arguments() );
  439. }
  440. // Good citizen: In the interest of efficiency, we assume
  441. // interceptors will be "good citizens" in that they will not
  442. // modify the contents of the Parameter[] array. We also assume
  443. // they will not change the values of the containing Anys.
  444. return cachedArguments;
  445. }
  446. /**
  447. * See RequestInfoImpl for javadoc.
  448. */
  449. public TypeCode[] exceptions (){
  450. checkAccess( MID_EXCEPTIONS );
  451. if( cachedExceptions == null ) {
  452. if( request == null ) {
  453. throw stdWrapper.piOperationNotSupported2() ;
  454. }
  455. // Get the list of exceptions from DII request data, If there are
  456. // no exceptions raised then this method will return null.
  457. ExceptionList excList = request.exceptions( );
  458. int count = excList.count();
  459. TypeCode[] excTCList = new TypeCode[count];
  460. try {
  461. for( int i = 0; i < count; i++ ) {
  462. excTCList[i] = excList.item( i );
  463. }
  464. } catch( Exception e ) {
  465. throw wrapper.exceptionInExceptions( e ) ;
  466. }
  467. cachedExceptions = excTCList;
  468. }
  469. // Good citizen: In the interest of efficiency, we assume
  470. // interceptors will be "good citizens" in that they will not
  471. // modify the contents of the TypeCode[] array. We also assume
  472. // they will not change the values of the containing TypeCodes.
  473. return cachedExceptions;
  474. }
  475. /**
  476. * See RequestInfoImpl for javadoc.
  477. */
  478. public String[] contexts (){
  479. checkAccess( MID_CONTEXTS );
  480. if( cachedContexts == null ) {
  481. if( request == null ) {
  482. throw stdWrapper.piOperationNotSupported3() ;
  483. }
  484. // Get the list of contexts from DII request data, If there are
  485. // no contexts then this method will return null.
  486. ContextList ctxList = request.contexts( );
  487. int count = ctxList.count();
  488. String[] ctxListToReturn = new String[count];
  489. try {
  490. for( int i = 0; i < count; i++ ) {
  491. ctxListToReturn[i] = ctxList.item( i );
  492. }
  493. } catch( Exception e ) {
  494. throw wrapper.exceptionInContexts( e ) ;
  495. }
  496. cachedContexts = ctxListToReturn;
  497. }
  498. // Good citizen: In the interest of efficiency, we assume
  499. // interceptors will be "good citizens" in that they will not
  500. // modify the contents of the String[] array.
  501. return cachedContexts;
  502. }
  503. /**
  504. * See RequestInfoImpl for javadoc.
  505. */
  506. public String[] operation_context (){
  507. checkAccess( MID_OPERATION_CONTEXT );
  508. if( cachedOperationContext == null ) {
  509. if( request == null ) {
  510. throw stdWrapper.piOperationNotSupported4() ;
  511. }
  512. // Get the list of contexts from DII request data, If there are
  513. // no contexts then this method will return null.
  514. Context ctx = request.ctx( );
  515. // _REVISIT_ The API for get_values is not compliant with the spec,
  516. // Revisit this code once it's fixed.
  517. // _REVISIT_ Our ORB doesn't support Operation Context, This code
  518. // will not be excerscised until it's supported.
  519. // The first parameter in get_values is the start_scope which
  520. // if blank makes it as a global scope.
  521. // The second parameter is op_flags which is set to RESTRICT_SCOPE
  522. // As there is only one defined in the spec.
  523. // The Third param is the pattern which is '*' requiring it to
  524. // get all the contexts.
  525. NVList nvList = ctx.get_values( "", CTX_RESTRICT_SCOPE.value,"*" );
  526. String[] context = new String[(nvList.count() * 2) ];
  527. if( ( nvList != null ) &&( nvList.count() != 0 ) ) {
  528. // The String[] array will contain Name and Value for each
  529. // context and hence double the size in the array.
  530. int index = 0;
  531. for( int i = 0; i < nvList.count(); i++ ) {
  532. NamedValue nv;
  533. try {
  534. nv = nvList.item( i );
  535. }
  536. catch (Exception e ) {
  537. return (String[]) null;
  538. }
  539. context[index] = nv.name();
  540. index++;
  541. context[index] = nv.value().extract_string();
  542. index++;
  543. }
  544. }
  545. cachedOperationContext = context;
  546. }
  547. // Good citizen: In the interest of efficiency, we assume
  548. // interceptors will be "good citizens" in that they will not
  549. // modify the contents of the String[] array.
  550. return cachedOperationContext;
  551. }
  552. /**
  553. * See RequestInfoImpl for javadoc.
  554. */
  555. public Any result (){
  556. checkAccess( MID_RESULT );
  557. if( cachedResult == null ) {
  558. if( request == null ) {
  559. throw stdWrapper.piOperationNotSupported5() ;
  560. }
  561. // Get the result from the DII request data.
  562. NamedValue nvResult = request.result( );
  563. if( nvResult == null ) {
  564. throw wrapper.piDiiResultIsNull() ;
  565. }
  566. cachedResult = nvResult.value();
  567. }
  568. // Good citizen: In the interest of efficiency, we assume that
  569. // interceptors will not modify the contents of the result Any.
  570. // Otherwise, we would need to create a deep copy of the Any.
  571. return cachedResult;
  572. }
  573. /**
  574. * See RequestInfoImpl for javadoc.
  575. */
  576. public boolean response_expected (){
  577. // access is currently valid for all states:
  578. //checkAccess( MID_RESPONSE_EXPECTED );
  579. return ! messageMediator.isOneWay();
  580. }
  581. /**
  582. * See RequestInfoImpl for javadoc.
  583. */
  584. public Object forward_reference (){
  585. checkAccess( MID_FORWARD_REFERENCE );
  586. // Check to make sure we are in LOCATION_FORWARD
  587. // state as per ptc/00-08-06, table 21-1
  588. // footnote 2.
  589. if( replyStatus != LOCATION_FORWARD.value ) {
  590. throw stdWrapper.invalidPiCall1() ;
  591. }
  592. // Do not cache this value since if an interceptor raises
  593. // forward request then the next interceptor in the
  594. // list should see the new value.
  595. IOR ior = getLocatedIOR();
  596. return iorToObject(ior);
  597. }
  598. private IOR getLocatedIOR()
  599. {
  600. IOR ior;
  601. CorbaContactInfoList contactInfoList = (CorbaContactInfoList)
  602. messageMediator.getContactInfo().getContactInfoList();
  603. ior = contactInfoList.getEffectiveTargetIOR();
  604. return ior;
  605. }
  606. protected void setLocatedIOR(IOR ior)
  607. {
  608. ORB orb = (ORB) messageMediator.getBroker();
  609. CorbaContactInfoListIterator iterator = (CorbaContactInfoListIterator)
  610. ((CorbaInvocationInfo)orb.getInvocationInfo())
  611. .getContactInfoListIterator();
  612. // REVISIT - this most likely causes reportRedirect to happen twice.
  613. // Once here and once inside the request dispatcher.
  614. iterator.reportRedirect(
  615. (CorbaContactInfo)messageMediator.getContactInfo(),
  616. ior);
  617. }
  618. /**
  619. * See RequestInfoImpl for javadoc.
  620. */
  621. public org.omg.IOP.ServiceContext get_request_service_context( int id ) {
  622. checkAccess( MID_GET_REQUEST_SERVICE_CONTEXT );
  623. if( cachedRequestServiceContexts == null ) {
  624. cachedRequestServiceContexts = new HashMap();
  625. }
  626. return getServiceContext(cachedRequestServiceContexts,
  627. messageMediator.getRequestServiceContexts(),
  628. id);
  629. }
  630. /**
  631. * does not contain an etry for that ID, BAD_PARAM with a minor code of
  632. * TBD_BP is raised.
  633. */
  634. public org.omg.IOP.ServiceContext get_reply_service_context( int id ) {
  635. checkAccess( MID_GET_REPLY_SERVICE_CONTEXT );
  636. if( cachedReplyServiceContexts == null ) {
  637. cachedReplyServiceContexts = new HashMap();
  638. }
  639. // In the event this is called from a oneway, we will have no
  640. // response object.
  641. //
  642. // In the event this is called after a IIOPConnection.purgeCalls,
  643. // we will have a response object, but that object will
  644. // not contain a header (which would hold the service context
  645. // container). See bug 4624102.
  646. //
  647. // REVISIT: this is the only thing used
  648. // from response at this time. However, a more general solution
  649. // would avoid accessing other parts of response's header.
  650. //
  651. // Instead of throwing a NullPointer, we will
  652. // "gracefully" handle these with a BAD_PARAM with minor code 25.
  653. try {
  654. ServiceContexts serviceContexts =
  655. messageMediator.getReplyServiceContexts();
  656. if (serviceContexts == null) {
  657. throw new NullPointerException();
  658. }
  659. return getServiceContext(cachedReplyServiceContexts,
  660. serviceContexts, id);
  661. } catch (NullPointerException e) {
  662. // REVISIT how this is programmed - not what it does.
  663. // See purge calls test. The waiter is woken up by the
  664. // call to purge calls - but there is no reply containing
  665. // service contexts.
  666. throw stdWrapper.invalidServiceContextId( e ) ;
  667. }
  668. }
  669. //
  670. // REVISIT
  671. // Override RequestInfoImpl connection to work in framework.
  672. //
  673. public com.sun.corba.se.spi.legacy.connection.Connection connection()
  674. {
  675. return (com.sun.corba.se.spi.legacy.connection.Connection)
  676. messageMediator.getConnection();
  677. }
  678. /*
  679. **********************************************************************
  680. * Package-scope interfaces
  681. **********************************************************************/
  682. protected void setInfo(MessageMediator messageMediator)
  683. {
  684. this.messageMediator = (CorbaMessageMediator)messageMediator;
  685. // REVISIT - so mediator can handle DII in subcontract.
  686. this.messageMediator.setDIIInfo(request);
  687. }
  688. /**
  689. * Set or reset the retry request flag.
  690. */
  691. void setRetryRequest( boolean retryRequest ) {
  692. this.retryRequest = retryRequest;
  693. }
  694. /**
  695. * Retrieve the current retry request status.
  696. */
  697. boolean getRetryRequest() {
  698. return this.retryRequest;
  699. }
  700. /**
  701. * Increases the entry count by 1.
  702. */
  703. void incrementEntryCount() {
  704. this.entryCount++;
  705. }
  706. /**
  707. * Decreases the entry count by 1.
  708. */
  709. void decrementEntryCount() {
  710. this.entryCount--;
  711. }
  712. /**
  713. * Retrieve the current entry count
  714. */
  715. int getEntryCount() {
  716. return this.entryCount;
  717. }
  718. /**
  719. * Overridden from RequestInfoImpl. Calls the super class, then
  720. * sets the ending point call depending on the reply status.
  721. */
  722. protected void setReplyStatus( short replyStatus ) {
  723. super.setReplyStatus( replyStatus );
  724. switch( replyStatus ) {
  725. case SUCCESSFUL.value:
  726. endingPointCall = CALL_RECEIVE_REPLY;
  727. break;
  728. case SYSTEM_EXCEPTION.value:
  729. case USER_EXCEPTION.value:
  730. endingPointCall = CALL_RECEIVE_EXCEPTION;
  731. break;
  732. case LOCATION_FORWARD.value:
  733. case TRANSPORT_RETRY.value:
  734. endingPointCall = CALL_RECEIVE_OTHER;
  735. break;
  736. }
  737. }
  738. /**
  739. * Sets DII request object in the RequestInfoObject.
  740. */
  741. protected void setDIIRequest(org.omg.CORBA.Request req) {
  742. request = req;
  743. }
  744. /**
  745. * Keeps track of whether initiate was called for a DII request. The ORB
  746. * needs to know this so it knows whether to ignore a second call to
  747. * initiateClientPIRequest or not.
  748. */
  749. protected void setDIIInitiate( boolean diiInitiate ) {
  750. this.diiInitiate = diiInitiate;
  751. }
  752. /**
  753. * See comment for setDIIInitiate
  754. */
  755. protected boolean isDIIInitiate() {
  756. return this.diiInitiate;
  757. }
  758. /**
  759. * The PICurrent stack should only be popped if it was pushed.
  760. * This is generally the case. But exceptions which occur
  761. * after the stub's entry to _request but before the push
  762. * end up in _releaseReply which will try to pop unless told not to.
  763. */
  764. protected void setPICurrentPushed( boolean piCurrentPushed ) {
  765. this.piCurrentPushed = piCurrentPushed;
  766. }
  767. protected boolean isPICurrentPushed() {
  768. return this.piCurrentPushed;
  769. }
  770. /**
  771. * Overridden from RequestInfoImpl.
  772. */
  773. protected void setException( Exception exception ) {
  774. super.setException( exception );
  775. // Clear cached values:
  776. cachedReceivedException = null;
  777. cachedReceivedExceptionId = null;
  778. }
  779. protected boolean getIsOneWay() {
  780. return ! response_expected();
  781. }
  782. /**
  783. * See description for RequestInfoImpl.checkAccess
  784. */
  785. protected void checkAccess( int methodID )
  786. throws BAD_INV_ORDER
  787. {
  788. // Make sure currentPoint matches the appropriate index in the
  789. // validCall table:
  790. int validCallIndex = 0;
  791. switch( currentExecutionPoint ) {
  792. case EXECUTION_POINT_STARTING:
  793. switch( startingPointCall ) {
  794. case CALL_SEND_REQUEST:
  795. validCallIndex = 0;
  796. break;
  797. case CALL_SEND_POLL:
  798. validCallIndex = 1;
  799. break;
  800. }
  801. break;
  802. case EXECUTION_POINT_ENDING:
  803. switch( endingPointCall ) {
  804. case CALL_RECEIVE_REPLY:
  805. validCallIndex = 2;
  806. break;
  807. case CALL_RECEIVE_EXCEPTION:
  808. validCallIndex = 3;
  809. break;
  810. case CALL_RECEIVE_OTHER:
  811. validCallIndex = 4;
  812. break;
  813. }
  814. break;
  815. }
  816. // Check the validCall table:
  817. if( !validCall[methodID][validCallIndex] ) {
  818. throw stdWrapper.invalidPiCall2() ;
  819. }
  820. }
  821. }
  822. // End of file.