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