Sat, 01 Dec 2007 00:00:00 +0000
Initial load
1 /*
2 * Copyright 2000-2003 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any 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.transport.CorbaContactInfo;
78 import com.sun.corba.se.spi.transport.CorbaContactInfoList;
79 import com.sun.corba.se.spi.transport.CorbaContactInfoListIterator;
81 import com.sun.corba.se.impl.encoding.CDROutputStream;
82 import com.sun.corba.se.impl.encoding.CDRInputStream_1_0;
83 import com.sun.corba.se.impl.orbutil.ORBUtility;
84 import com.sun.corba.se.impl.protocol.CorbaInvocationInfo;
85 import com.sun.corba.se.impl.util.RepositoryId;
87 /**
88 * Implementation of the ClientRequestInfo interface as specified in
89 * orbos/99-12-02 section 5.4.2.
90 */
91 public final class ClientRequestInfoImpl
92 extends RequestInfoImpl
93 implements ClientRequestInfo
94 {
96 // The available constants for startingPointCall
97 static final int CALL_SEND_REQUEST = 0;
98 static final int CALL_SEND_POLL = 1;
100 // The available constants for endingPointCall
101 static final int CALL_RECEIVE_REPLY = 0;
102 static final int CALL_RECEIVE_EXCEPTION = 1;
103 static final int CALL_RECEIVE_OTHER = 2;
105 //////////////////////////////////////////////////////////////////////
106 //
107 // NOTE: IF AN ATTRIBUTE IS ADDED, PLEASE UPDATE RESET();
108 //
109 //////////////////////////////////////////////////////////////////////
111 // The current retry request status. True if this request is being
112 // retried and this info object is to be reused, or false otherwise.
113 private boolean retryRequest;
115 // The number of times this info object has been (re)used. This is
116 // incremented every time a request is retried, and decremented every
117 // time a request is complete. When this reaches zero, the info object
118 // is popped from the ClientRequestInfoImpl ThreadLocal stack in the ORB.
119 private int entryCount = 0;
121 // The RequestImpl is set when the call is DII based.
122 // The DII query calls like ParameterList, ExceptionList,
123 // ContextList will be delegated to RequestImpl.
124 private org.omg.CORBA.Request request;
126 // Sources of client request information
127 private boolean diiInitiate;
128 private CorbaMessageMediator messageMediator;
130 // Cached information:
131 private org.omg.CORBA.Object cachedTargetObject;
132 private org.omg.CORBA.Object cachedEffectiveTargetObject;
133 private Parameter[] cachedArguments;
134 private TypeCode[] cachedExceptions;
135 private String[] cachedContexts;
136 private String[] cachedOperationContext;
137 private String cachedReceivedExceptionId;
138 private Any cachedResult;
139 private Any cachedReceivedException;
140 private TaggedProfile cachedEffectiveProfile;
141 // key = Integer, value = IOP.ServiceContext.
142 private HashMap cachedRequestServiceContexts;
143 // key = Integer, value = IOP.ServiceContext.
144 private HashMap cachedReplyServiceContexts;
145 // key = Integer, value = TaggedComponent
146 private HashMap cachedEffectiveComponents;
149 protected boolean piCurrentPushed;
151 //////////////////////////////////////////////////////////////////////
152 //
153 // NOTE: IF AN ATTRIBUTE IS ADDED, PLEASE UPDATE RESET();
154 //
155 //////////////////////////////////////////////////////////////////////
157 /**
158 * Reset the info object so that it can be reused for a retry,
159 * for example.
160 */
161 void reset() {
162 super.reset();
164 // Please keep these in the same order that they're declared above.
166 retryRequest = false;
168 // Do not reset entryCount because we need to know when to pop this
169 // from the stack.
171 request = null;
172 diiInitiate = false;
173 messageMediator = null;
175 // Clear cached attributes:
176 cachedTargetObject = null;
177 cachedEffectiveTargetObject = null;
178 cachedArguments = null;
179 cachedExceptions = null;
180 cachedContexts = null;
181 cachedOperationContext = null;
182 cachedReceivedExceptionId = null;
183 cachedResult = null;
184 cachedReceivedException = null;
185 cachedEffectiveProfile = null;
186 cachedRequestServiceContexts = null;
187 cachedReplyServiceContexts = null;
188 cachedEffectiveComponents = null;
190 piCurrentPushed = false;
192 startingPointCall = CALL_SEND_REQUEST;
193 endingPointCall = CALL_RECEIVE_REPLY;
195 }
197 /*
198 **********************************************************************
199 * Access protection
200 **********************************************************************/
202 // Method IDs for all methods in ClientRequestInfo. This allows for a
203 // convenient O(1) lookup for checkAccess().
204 protected static final int MID_TARGET = MID_RI_LAST + 1;
205 protected static final int MID_EFFECTIVE_TARGET = MID_RI_LAST + 2;
206 protected static final int MID_EFFECTIVE_PROFILE = MID_RI_LAST + 3;
207 protected static final int MID_RECEIVED_EXCEPTION = MID_RI_LAST + 4;
208 protected static final int MID_RECEIVED_EXCEPTION_ID = MID_RI_LAST + 5;
209 protected static final int MID_GET_EFFECTIVE_COMPONENT = MID_RI_LAST + 6;
210 protected static final int MID_GET_EFFECTIVE_COMPONENTS
211 = MID_RI_LAST + 7;
212 protected static final int MID_GET_REQUEST_POLICY = MID_RI_LAST + 8;
213 protected static final int MID_ADD_REQUEST_SERVICE_CONTEXT
214 = MID_RI_LAST + 9;
216 // ClientRequestInfo validity table (see ptc/00-08-06 table 21-1).
217 // Note: These must be in the same order as specified in contants.
218 protected static final boolean validCall[][] = {
219 // LEGEND:
220 // s_req = send_request r_rep = receive_reply
221 // s_pol = send_poll r_exc = receive_exception
222 // r_oth = receive_other
223 //
224 // A true value indicates call is valid at specified point.
225 // A false value indicates the call is invalid.
226 //
227 //
228 // NOTE: If the order or number of columns change, update
229 // checkAccess() accordingly.
230 //
231 // { s_req, s_pol, r_rep, r_exc, r_oth }
232 // RequestInfo methods:
233 /*request_id*/ { true , true , true , true , true },
234 /*operation*/ { true , true , true , true , true },
235 /*arguments*/ { true , false, true , false, false },
236 /*exceptions*/ { true , false, true , true , true },
237 /*contexts*/ { true , false, true , true , true },
238 /*operation_context*/ { true , false, true , true , true },
239 /*result*/ { false, false, true , false, false },
240 /*response_expected*/ { true , true , true , true , true },
241 /*sync_scope*/ { true , false, true , true , true },
242 /*reply_status*/ { false, false, true , true , true },
243 /*forward_reference*/ { false, false, false, false, true },
244 /*get_slot*/ { true , true , true , true , true },
245 /*get_request_service_context*/ { true , false, true , true , true },
246 /*get_reply_service_context*/ { false, false, true , true , true },
247 //
248 // ClientRequestInfo methods::
249 /*target*/ { true , true , true , true , true },
250 /*effective_target*/ { true , true , true , true , true },
251 /*effective_profile*/ { true , true , true , true , true },
252 /*received_exception*/ { false, false, false, true , false },
253 /*received_exception_id*/ { false, false, false, true , false },
254 /*get_effective_component*/ { true , false, true , true , true },
255 /*get_effective_components*/ { true , false, true , true , true },
256 /*get_request_policy*/ { true , false, true , true , true },
257 /*add_request_service_context*/ { true , false, false, false, false }
258 };
261 /*
262 **********************************************************************
263 * Public ClientRequestInfo interfaces
264 **********************************************************************/
266 /**
267 * Creates a new ClientRequestInfo implementation.
268 * The constructor is package scope since no other package need create
269 * an instance of this class.
270 */
271 protected ClientRequestInfoImpl( ORB myORB ) {
272 super( myORB );
273 startingPointCall = CALL_SEND_REQUEST;
274 endingPointCall = CALL_RECEIVE_REPLY;
275 }
277 /**
278 * The object which the client called to perform the operation.
279 */
280 public org.omg.CORBA.Object target (){
281 // access is currently valid for all states:
282 //checkAccess( MID_TARGET );
283 if (cachedTargetObject == null) {
284 CorbaContactInfo corbaContactInfo = (CorbaContactInfo)
285 messageMediator.getContactInfo();
286 cachedTargetObject =
287 iorToObject(corbaContactInfo.getTargetIOR());
288 }
289 return cachedTargetObject;
290 }
292 /**
293 * The actual object on which the operation will be invoked. If the
294 * reply_status is LOCATION_FORWARD, then on subsequent requests,
295 * effective_target will contain the forwarded IOR while target will
296 * remain unchanged.
297 */
298 public org.omg.CORBA.Object effective_target() {
299 // access is currently valid for all states:
300 //checkAccess( MID_EFFECTIVE_TARGET );
302 // Note: This is not necessarily the same as locatedIOR.
303 // Reason: See the way we handle COMM_FAILURES in
304 // ClientRequestDispatcher.createRequest, v1.32
306 if (cachedEffectiveTargetObject == null) {
307 CorbaContactInfo corbaContactInfo = (CorbaContactInfo)
308 messageMediator.getContactInfo();
309 // REVISIT - get through chain like getLocatedIOR helper below.
310 cachedEffectiveTargetObject =
311 iorToObject(corbaContactInfo.getEffectiveTargetIOR());
312 }
313 return cachedEffectiveTargetObject;
314 }
316 /**
317 * The profile that will be used to send the request. If a location
318 * forward has occurred for this operation's object and that object's
319 * profile change accordingly, then this profile will be that located
320 * profile.
321 */
322 public TaggedProfile effective_profile (){
323 // access is currently valid for all states:
324 //checkAccess( MID_EFFECTIVE_PROFILE );
326 if( cachedEffectiveProfile == null ) {
327 CorbaContactInfo corbaContactInfo = (CorbaContactInfo)
328 messageMediator.getContactInfo();
329 cachedEffectiveProfile =
330 corbaContactInfo.getEffectiveProfile().getIOPProfile();
331 }
333 // Good citizen: In the interest of efficiency, we assume interceptors
334 // will not modify the returned TaggedProfile in any way so we need
335 // not make a deep copy of it.
337 return cachedEffectiveProfile;
338 }
340 /**
341 * Contains the exception to be returned to the client.
342 */
343 public Any received_exception (){
344 checkAccess( MID_RECEIVED_EXCEPTION );
346 if( cachedReceivedException == null ) {
347 cachedReceivedException = exceptionToAny( exception );
348 }
350 // Good citizen: In the interest of efficiency, we assume interceptors
351 // will not modify the returned Any in any way so we need
352 // not make a deep copy of it.
354 return cachedReceivedException;
355 }
357 /**
358 * The CORBA::RepositoryId of the exception to be returned to the client.
359 */
360 public String received_exception_id (){
361 checkAccess( MID_RECEIVED_EXCEPTION_ID );
363 if( cachedReceivedExceptionId == null ) {
364 String result = null;
366 if( exception == null ) {
367 // Note: exception should never be null here since we will
368 // throw a BAD_INV_ORDER if this is not called from
369 // receive_exception.
370 throw wrapper.exceptionWasNull() ;
371 } else if( exception instanceof SystemException ) {
372 String name = exception.getClass().getName();
373 result = ORBUtility.repositoryIdOf(name);
374 } else if( exception instanceof ApplicationException ) {
375 result = ((ApplicationException)exception).getId();
376 }
378 // _REVISIT_ We need to be able to handle a UserException in the
379 // DII case. How do we extract the ID from a UserException?
381 cachedReceivedExceptionId = result;
382 }
384 return cachedReceivedExceptionId;
385 }
387 /**
388 * Returns the IOP::TaggedComponent with the given ID from the profile
389 * selected for this request. IF there is more than one component for a
390 * given component ID, it is undefined which component this operation
391 * returns (get_effective_component should be called instead).
392 */
393 public TaggedComponent get_effective_component (int id){
394 checkAccess( MID_GET_EFFECTIVE_COMPONENT );
396 return get_effective_components( id )[0];
397 }
399 /**
400 * Returns all the tagged components with the given ID from the profile
401 * selected for this request.
402 */
403 public TaggedComponent[] get_effective_components (int id){
404 checkAccess( MID_GET_EFFECTIVE_COMPONENTS );
405 Integer integerId = new Integer( id );
406 TaggedComponent[] result = null;
407 boolean justCreatedCache = false;
409 if( cachedEffectiveComponents == null ) {
410 cachedEffectiveComponents = new HashMap();
411 justCreatedCache = true;
412 }
413 else {
414 // Look in cache:
415 result = (TaggedComponent[])cachedEffectiveComponents.get(
416 integerId );
417 }
419 // null could mean we cached null or not in cache.
420 if( (result == null) &&
421 (justCreatedCache ||
422 !cachedEffectiveComponents.containsKey( integerId ) ) )
423 {
424 // Not in cache. Get it from the profile:
425 CorbaContactInfo corbaContactInfo = (CorbaContactInfo)
426 messageMediator.getContactInfo();
427 IIOPProfileTemplate ptemp =
428 (IIOPProfileTemplate)corbaContactInfo.getEffectiveProfile().
429 getTaggedProfileTemplate();
430 result = ptemp.getIOPComponents(myORB, id);
431 cachedEffectiveComponents.put( integerId, result );
432 }
434 // As per ptc/00-08-06, section 21.3.13.6., If not found, raise
435 // BAD_PARAM with minor code INVALID_COMPONENT_ID.
436 if( (result == null) || (result.length == 0) ) {
437 throw stdWrapper.invalidComponentId( integerId ) ;
438 }
440 // Good citizen: In the interest of efficiency, we will assume
441 // interceptors will not modify the returned TaggedCompoent[], or
442 // the TaggedComponents inside of it. Otherwise, we would need to
443 // clone the array and make a deep copy of its contents.
445 return result;
446 }
448 /**
449 * Returns the given policy in effect for this operation.
450 */
451 public Policy get_request_policy (int type){
452 checkAccess( MID_GET_REQUEST_POLICY );
453 // _REVISIT_ Our ORB is not policy-based at this time.
454 throw wrapper.piOrbNotPolicyBased() ;
455 }
457 /**
458 * Allows interceptors to add service contexts to the request.
459 * <p>
460 * There is no declaration of the order of the service contexts. They
461 * may or may not appear in the order they are added.
462 */
463 public void add_request_service_context (ServiceContext service_context,
464 boolean replace)
465 {
466 checkAccess( MID_ADD_REQUEST_SERVICE_CONTEXT );
468 if( cachedRequestServiceContexts == null ) {
469 cachedRequestServiceContexts = new HashMap();
470 }
472 addServiceContext( cachedRequestServiceContexts,
473 messageMediator.getRequestServiceContexts(),
474 service_context, replace );
475 }
477 // NOTE: When adding a method, be sure to:
478 // 1. Add a MID_* constant for that method
479 // 2. Call checkAccess at the start of the method
480 // 3. Define entries in the validCall[][] table for interception points.
482 /*
483 **********************************************************************
484 * Public RequestInfo interfaces
485 *
486 * These are implemented here because they have differing
487 * implementations depending on whether this is a client or a server
488 * request info object.
489 **********************************************************************/
491 /**
492 * See RequestInfoImpl for javadoc.
493 */
494 public int request_id (){
495 // access is currently valid for all states:
496 //checkAccess( MID_REQUEST_ID );
497 /*
498 * NOTE: The requestId in client interceptors is the same as the
499 * GIOP request id. This works because both interceptors and
500 * request ids are scoped by the ORB on the client side.
501 */
502 return messageMediator.getRequestId();
503 }
505 /**
506 * See RequestInfoImpl for javadoc.
507 */
508 public String operation (){
509 // access is currently valid for all states:
510 //checkAccess( MID_OPERATION );
511 return messageMediator.getOperationName();
512 }
514 /**
515 * See RequestInfoImpl for javadoc.
516 */
517 public Parameter[] arguments (){
518 checkAccess( MID_ARGUMENTS );
520 if( cachedArguments == null ) {
521 if( request == null ) {
522 throw stdWrapper.piOperationNotSupported1() ;
523 }
525 // If it is DII request then get the arguments from the DII req
526 // and convert that into parameters.
527 cachedArguments = nvListToParameterArray( request.arguments() );
528 }
530 // Good citizen: In the interest of efficiency, we assume
531 // interceptors will be "good citizens" in that they will not
532 // modify the contents of the Parameter[] array. We also assume
533 // they will not change the values of the containing Anys.
535 return cachedArguments;
536 }
538 /**
539 * See RequestInfoImpl for javadoc.
540 */
541 public TypeCode[] exceptions (){
542 checkAccess( MID_EXCEPTIONS );
544 if( cachedExceptions == null ) {
545 if( request == null ) {
546 throw stdWrapper.piOperationNotSupported2() ;
547 }
549 // Get the list of exceptions from DII request data, If there are
550 // no exceptions raised then this method will return null.
551 ExceptionList excList = request.exceptions( );
552 int count = excList.count();
553 TypeCode[] excTCList = new TypeCode[count];
554 try {
555 for( int i = 0; i < count; i++ ) {
556 excTCList[i] = excList.item( i );
557 }
558 } catch( Exception e ) {
559 throw wrapper.exceptionInExceptions( e ) ;
560 }
562 cachedExceptions = excTCList;
563 }
565 // Good citizen: In the interest of efficiency, we assume
566 // interceptors will be "good citizens" in that they will not
567 // modify the contents of the TypeCode[] array. We also assume
568 // they will not change the values of the containing TypeCodes.
570 return cachedExceptions;
571 }
573 /**
574 * See RequestInfoImpl for javadoc.
575 */
576 public String[] contexts (){
577 checkAccess( MID_CONTEXTS );
579 if( cachedContexts == null ) {
580 if( request == null ) {
581 throw stdWrapper.piOperationNotSupported3() ;
582 }
584 // Get the list of contexts from DII request data, If there are
585 // no contexts then this method will return null.
586 ContextList ctxList = request.contexts( );
587 int count = ctxList.count();
588 String[] ctxListToReturn = new String[count];
589 try {
590 for( int i = 0; i < count; i++ ) {
591 ctxListToReturn[i] = ctxList.item( i );
592 }
593 } catch( Exception e ) {
594 throw wrapper.exceptionInContexts( e ) ;
595 }
597 cachedContexts = ctxListToReturn;
598 }
600 // Good citizen: In the interest of efficiency, we assume
601 // interceptors will be "good citizens" in that they will not
602 // modify the contents of the String[] array.
604 return cachedContexts;
605 }
607 /**
608 * See RequestInfoImpl for javadoc.
609 */
610 public String[] operation_context (){
611 checkAccess( MID_OPERATION_CONTEXT );
613 if( cachedOperationContext == null ) {
614 if( request == null ) {
615 throw stdWrapper.piOperationNotSupported4() ;
616 }
618 // Get the list of contexts from DII request data, If there are
619 // no contexts then this method will return null.
620 Context ctx = request.ctx( );
621 // _REVISIT_ The API for get_values is not compliant with the spec,
622 // Revisit this code once it's fixed.
623 // _REVISIT_ Our ORB doesn't support Operation Context, This code
624 // will not be excerscised until it's supported.
625 // The first parameter in get_values is the start_scope which
626 // if blank makes it as a global scope.
627 // The second parameter is op_flags which is set to RESTRICT_SCOPE
628 // As there is only one defined in the spec.
629 // The Third param is the pattern which is '*' requiring it to
630 // get all the contexts.
631 NVList nvList = ctx.get_values( "", CTX_RESTRICT_SCOPE.value,"*" );
632 String[] context = new String[(nvList.count() * 2) ];
633 if( ( nvList != null ) &&( nvList.count() != 0 ) ) {
634 // The String[] array will contain Name and Value for each
635 // context and hence double the size in the array.
636 int index = 0;
637 for( int i = 0; i < nvList.count(); i++ ) {
638 NamedValue nv;
639 try {
640 nv = nvList.item( i );
641 }
642 catch (Exception e ) {
643 return (String[]) null;
644 }
645 context[index] = nv.name();
646 index++;
647 context[index] = nv.value().extract_string();
648 index++;
649 }
650 }
652 cachedOperationContext = context;
653 }
655 // Good citizen: In the interest of efficiency, we assume
656 // interceptors will be "good citizens" in that they will not
657 // modify the contents of the String[] array.
659 return cachedOperationContext;
660 }
662 /**
663 * See RequestInfoImpl for javadoc.
664 */
665 public Any result (){
666 checkAccess( MID_RESULT );
668 if( cachedResult == null ) {
669 if( request == null ) {
670 throw stdWrapper.piOperationNotSupported5() ;
671 }
672 // Get the result from the DII request data.
673 NamedValue nvResult = request.result( );
675 if( nvResult == null ) {
676 throw wrapper.piDiiResultIsNull() ;
677 }
679 cachedResult = nvResult.value();
680 }
682 // Good citizen: In the interest of efficiency, we assume that
683 // interceptors will not modify the contents of the result Any.
684 // Otherwise, we would need to create a deep copy of the Any.
686 return cachedResult;
687 }
689 /**
690 * See RequestInfoImpl for javadoc.
691 */
692 public boolean response_expected (){
693 // access is currently valid for all states:
694 //checkAccess( MID_RESPONSE_EXPECTED );
695 return ! messageMediator.isOneWay();
696 }
698 /**
699 * See RequestInfoImpl for javadoc.
700 */
701 public Object forward_reference (){
702 checkAccess( MID_FORWARD_REFERENCE );
703 // Check to make sure we are in LOCATION_FORWARD
704 // state as per ptc/00-08-06, table 21-1
705 // footnote 2.
706 if( replyStatus != LOCATION_FORWARD.value ) {
707 throw stdWrapper.invalidPiCall1() ;
708 }
710 // Do not cache this value since if an interceptor raises
711 // forward request then the next interceptor in the
712 // list should see the new value.
713 IOR ior = getLocatedIOR();
714 return iorToObject(ior);
715 }
717 private IOR getLocatedIOR()
718 {
719 IOR ior;
720 CorbaContactInfoList contactInfoList = (CorbaContactInfoList)
721 messageMediator.getContactInfo().getContactInfoList();
722 ior = contactInfoList.getEffectiveTargetIOR();
723 return ior;
724 }
726 protected void setLocatedIOR(IOR ior)
727 {
728 ORB orb = (ORB) messageMediator.getBroker();
730 CorbaContactInfoListIterator iterator = (CorbaContactInfoListIterator)
731 ((CorbaInvocationInfo)orb.getInvocationInfo())
732 .getContactInfoListIterator();
734 // REVISIT - this most likely causes reportRedirect to happen twice.
735 // Once here and once inside the request dispatcher.
736 iterator.reportRedirect(
737 (CorbaContactInfo)messageMediator.getContactInfo(),
738 ior);
739 }
741 /**
742 * See RequestInfoImpl for javadoc.
743 */
744 public org.omg.IOP.ServiceContext get_request_service_context( int id ) {
745 checkAccess( MID_GET_REQUEST_SERVICE_CONTEXT );
747 if( cachedRequestServiceContexts == null ) {
748 cachedRequestServiceContexts = new HashMap();
749 }
751 return getServiceContext(cachedRequestServiceContexts,
752 messageMediator.getRequestServiceContexts(),
753 id);
754 }
756 /**
757 * does not contain an etry for that ID, BAD_PARAM with a minor code of
758 * TBD_BP is raised.
759 */
760 public org.omg.IOP.ServiceContext get_reply_service_context( int id ) {
761 checkAccess( MID_GET_REPLY_SERVICE_CONTEXT );
763 if( cachedReplyServiceContexts == null ) {
764 cachedReplyServiceContexts = new HashMap();
765 }
767 // In the event this is called from a oneway, we will have no
768 // response object.
769 //
770 // In the event this is called after a IIOPConnection.purgeCalls,
771 // we will have a response object, but that object will
772 // not contain a header (which would hold the service context
773 // container). See bug 4624102.
774 //
775 // REVISIT: this is the only thing used
776 // from response at this time. However, a more general solution
777 // would avoid accessing other parts of response's header.
778 //
779 // Instead of throwing a NullPointer, we will
780 // "gracefully" handle these with a BAD_PARAM with minor code 25.
782 try {
783 ServiceContexts serviceContexts =
784 messageMediator.getReplyServiceContexts();
785 if (serviceContexts == null) {
786 throw new NullPointerException();
787 }
788 return getServiceContext(cachedReplyServiceContexts,
789 serviceContexts, id);
790 } catch (NullPointerException e) {
791 // REVISIT how this is programmed - not what it does.
792 // See purge calls test. The waiter is woken up by the
793 // call to purge calls - but there is no reply containing
794 // service contexts.
795 throw stdWrapper.invalidServiceContextId( e ) ;
796 }
797 }
799 //
800 // REVISIT
801 // Override RequestInfoImpl connection to work in framework.
802 //
804 public com.sun.corba.se.spi.legacy.connection.Connection connection()
805 {
806 return (com.sun.corba.se.spi.legacy.connection.Connection)
807 messageMediator.getConnection();
808 }
812 /*
813 **********************************************************************
814 * Package-scope interfaces
815 **********************************************************************/
817 protected void setInfo(MessageMediator messageMediator)
818 {
819 this.messageMediator = (CorbaMessageMediator)messageMediator;
820 // REVISIT - so mediator can handle DII in subcontract.
821 this.messageMediator.setDIIInfo(request);
822 }
824 /**
825 * Set or reset the retry request flag.
826 */
827 void setRetryRequest( boolean retryRequest ) {
828 this.retryRequest = retryRequest;
829 }
831 /**
832 * Retrieve the current retry request status.
833 */
834 boolean getRetryRequest() {
835 return this.retryRequest;
836 }
838 /**
839 * Increases the entry count by 1.
840 */
841 void incrementEntryCount() {
842 this.entryCount++;
843 }
845 /**
846 * Decreases the entry count by 1.
847 */
848 void decrementEntryCount() {
849 this.entryCount--;
850 }
852 /**
853 * Retrieve the current entry count
854 */
855 int getEntryCount() {
856 return this.entryCount;
857 }
859 /**
860 * Overridden from RequestInfoImpl. Calls the super class, then
861 * sets the ending point call depending on the reply status.
862 */
863 protected void setReplyStatus( short replyStatus ) {
864 super.setReplyStatus( replyStatus );
865 switch( replyStatus ) {
866 case SUCCESSFUL.value:
867 endingPointCall = CALL_RECEIVE_REPLY;
868 break;
869 case SYSTEM_EXCEPTION.value:
870 case USER_EXCEPTION.value:
871 endingPointCall = CALL_RECEIVE_EXCEPTION;
872 break;
873 case LOCATION_FORWARD.value:
874 case TRANSPORT_RETRY.value:
875 endingPointCall = CALL_RECEIVE_OTHER;
876 break;
877 }
878 }
880 /**
881 * Sets DII request object in the RequestInfoObject.
882 */
883 protected void setDIIRequest(org.omg.CORBA.Request req) {
884 request = req;
885 }
887 /**
888 * Keeps track of whether initiate was called for a DII request. The ORB
889 * needs to know this so it knows whether to ignore a second call to
890 * initiateClientPIRequest or not.
891 */
892 protected void setDIIInitiate( boolean diiInitiate ) {
893 this.diiInitiate = diiInitiate;
894 }
896 /**
897 * See comment for setDIIInitiate
898 */
899 protected boolean isDIIInitiate() {
900 return this.diiInitiate;
901 }
903 /**
904 * The PICurrent stack should only be popped if it was pushed.
905 * This is generally the case. But exceptions which occur
906 * after the stub's entry to _request but before the push
907 * end up in _releaseReply which will try to pop unless told not to.
908 */
909 protected void setPICurrentPushed( boolean piCurrentPushed ) {
910 this.piCurrentPushed = piCurrentPushed;
911 }
913 protected boolean isPICurrentPushed() {
914 return this.piCurrentPushed;
915 }
917 /**
918 * Overridden from RequestInfoImpl.
919 */
920 protected void setException( Exception exception ) {
921 super.setException( exception );
923 // Clear cached values:
924 cachedReceivedException = null;
925 cachedReceivedExceptionId = null;
926 }
928 protected boolean getIsOneWay() {
929 return ! response_expected();
930 }
932 /**
933 * See description for RequestInfoImpl.checkAccess
934 */
935 protected void checkAccess( int methodID )
936 throws BAD_INV_ORDER
937 {
938 // Make sure currentPoint matches the appropriate index in the
939 // validCall table:
940 int validCallIndex = 0;
941 switch( currentExecutionPoint ) {
942 case EXECUTION_POINT_STARTING:
943 switch( startingPointCall ) {
944 case CALL_SEND_REQUEST:
945 validCallIndex = 0;
946 break;
947 case CALL_SEND_POLL:
948 validCallIndex = 1;
949 break;
950 }
951 break;
952 case EXECUTION_POINT_ENDING:
953 switch( endingPointCall ) {
954 case CALL_RECEIVE_REPLY:
955 validCallIndex = 2;
956 break;
957 case CALL_RECEIVE_EXCEPTION:
958 validCallIndex = 3;
959 break;
960 case CALL_RECEIVE_OTHER:
961 validCallIndex = 4;
962 break;
963 }
964 break;
965 }
967 // Check the validCall table:
968 if( !validCall[methodID][validCallIndex] ) {
969 throw stdWrapper.invalidPiCall2() ;
970 }
971 }
973 }
975 // End of file.