FileDocCategorySizeDatePackage
ClientRequestInfoImpl.javaAPI DocJava SE 5 API32242Fri Aug 26 14:54:22 BST 2005com.sun.corba.se.impl.interceptors

ClientRequestInfoImpl

public final class ClientRequestInfoImpl extends RequestInfoImpl implements org.omg.PortableInterceptor.ClientRequestInfo
Implementation of the ClientRequestInfo interface as specified in orbos/99-12-02 section 5.4.2.

Fields Summary
static final int
CALL_SEND_REQUEST
static final int
CALL_SEND_POLL
static final int
CALL_RECEIVE_REPLY
static final int
CALL_RECEIVE_EXCEPTION
static final int
CALL_RECEIVE_OTHER
private boolean
retryRequest
private int
entryCount
private org.omg.CORBA.Request
request
private boolean
diiInitiate
private com.sun.corba.se.spi.protocol.CorbaMessageMediator
messageMediator
private org.omg.CORBA.Object
cachedTargetObject
private org.omg.CORBA.Object
cachedEffectiveTargetObject
private org.omg.Dynamic.Parameter[]
cachedArguments
private org.omg.CORBA.TypeCode[]
cachedExceptions
private String[]
cachedContexts
private String[]
cachedOperationContext
private String
cachedReceivedExceptionId
private org.omg.CORBA.Any
cachedResult
private org.omg.CORBA.Any
cachedReceivedException
private org.omg.IOP.TaggedProfile
cachedEffectiveProfile
private HashMap
cachedRequestServiceContexts
private HashMap
cachedReplyServiceContexts
private HashMap
cachedEffectiveComponents
protected boolean
piCurrentPushed
protected static final int
MID_TARGET
protected static final int
MID_EFFECTIVE_TARGET
protected static final int
MID_EFFECTIVE_PROFILE
protected static final int
MID_RECEIVED_EXCEPTION
protected static final int
MID_RECEIVED_EXCEPTION_ID
protected static final int
MID_GET_EFFECTIVE_COMPONENT
protected static final int
MID_GET_EFFECTIVE_COMPONENTS
protected static final int
MID_GET_REQUEST_POLICY
protected static final int
MID_ADD_REQUEST_SERVICE_CONTEXT
protected static final boolean[]
validCall
Constructors Summary
protected ClientRequestInfoImpl(com.sun.corba.se.spi.orb.ORB myORB)
Creates a new ClientRequestInfo implementation. The constructor is package scope since no other package need create an instance of this class.

    

    /*
     **********************************************************************
     * Public ClientRequestInfo interfaces
     **********************************************************************/
    
                              
          
        super( myORB ); 
        startingPointCall = CALL_SEND_REQUEST;
        endingPointCall = CALL_RECEIVE_REPLY;
    
Methods Summary
public voidadd_request_service_context(org.omg.IOP.ServiceContext service_context, boolean replace)
Allows interceptors to add service contexts to the request.

There is no declaration of the order of the service contexts. They may or may not appear in the order they are added.

        checkAccess( MID_ADD_REQUEST_SERVICE_CONTEXT );

	if( cachedRequestServiceContexts == null ) {
	    cachedRequestServiceContexts = new HashMap();
	}

	addServiceContext( cachedRequestServiceContexts, 
			   messageMediator.getRequestServiceContexts(),
			   service_context, replace );
    
public org.omg.Dynamic.Parameter[]arguments()
See RequestInfoImpl for javadoc.

        checkAccess( MID_ARGUMENTS );

	if( cachedArguments == null ) {
	    if( request == null ) {
		throw stdWrapper.piOperationNotSupported1() ;
	    }

	    // If it is DII request then get the arguments from the DII req
	    // and convert that into parameters.
	    cachedArguments = nvListToParameterArray( request.arguments() );
	}

        // Good citizen: In the interest of efficiency, we assume 
        // interceptors will be "good citizens" in that they will not 
        // modify the contents of the Parameter[] array.  We also assume 
        // they will not change the values of the containing Anys.

	return cachedArguments;
    
protected voidcheckAccess(int methodID)
See description for RequestInfoImpl.checkAccess

        // Make sure currentPoint matches the appropriate index in the
        // validCall table:
        int validCallIndex = 0;
        switch( currentExecutionPoint ) {
        case EXECUTION_POINT_STARTING:
            switch( startingPointCall ) {
            case CALL_SEND_REQUEST:
                validCallIndex = 0;
                break;
            case CALL_SEND_POLL:
                validCallIndex = 1;
                break;
            }
            break;
        case EXECUTION_POINT_ENDING:
            switch( endingPointCall ) {
            case CALL_RECEIVE_REPLY:
                validCallIndex = 2;
                break;
            case CALL_RECEIVE_EXCEPTION:
                validCallIndex = 3;
                break;
            case CALL_RECEIVE_OTHER:
                validCallIndex = 4;
                break;
            }
            break;
        }
        
        // Check the validCall table:
        if( !validCall[methodID][validCallIndex] ) {
	    throw stdWrapper.invalidPiCall2() ;
        }
    
public com.sun.corba.se.spi.legacy.connection.Connectionconnection()

	return (com.sun.corba.se.spi.legacy.connection.Connection) 
	    messageMediator.getConnection();
    
public java.lang.String[]contexts()
See RequestInfoImpl for javadoc.

        checkAccess( MID_CONTEXTS );

	if( cachedContexts == null ) {
	    if( request == null ) {
		throw stdWrapper.piOperationNotSupported3() ;
	    }

	    // Get the list of contexts from DII request data, If there are
	    // no contexts then this method will return null.
	    ContextList ctxList = request.contexts( );
	    int count = ctxList.count();
	    String[] ctxListToReturn = new String[count];
	    try {
		for( int i = 0; i < count; i++ ) {
		    ctxListToReturn[i] = ctxList.item( i );
		}
	    } catch( Exception e ) {
		throw wrapper.exceptionInContexts( e ) ;
	    }

            cachedContexts = ctxListToReturn;
	}

        // Good citizen: In the interest of efficiency, we assume 
        // interceptors will be "good citizens" in that they will not 
        // modify the contents of the String[] array.  

	return cachedContexts;
    
voiddecrementEntryCount()
Decreases the entry count by 1.

        this.entryCount--;
    
public org.omg.IOP.TaggedProfileeffective_profile()
The profile that will be used to send the request. If a location forward has occurred for this operation's object and that object's profile change accordingly, then this profile will be that located profile.

        // access is currently valid for all states:
        //checkAccess( MID_EFFECTIVE_PROFILE );

	if( cachedEffectiveProfile == null ) {
	    CorbaContactInfo corbaContactInfo = (CorbaContactInfo)
		messageMediator.getContactInfo();
	    cachedEffectiveProfile =
		corbaContactInfo.getEffectiveProfile().getIOPProfile();
	}

	// Good citizen: In the interest of efficiency, we assume interceptors
	// will not modify the returned TaggedProfile in any way so we need
	// not make a deep copy of it.

	return cachedEffectiveProfile;
    
public org.omg.CORBA.Objecteffective_target()
The actual object on which the operation will be invoked. If the reply_status is LOCATION_FORWARD, then on subsequent requests, effective_target will contain the forwarded IOR while target will remain unchanged.

	// access is currently valid for all states:
        //checkAccess( MID_EFFECTIVE_TARGET );

        // Note: This is not necessarily the same as locatedIOR.
        // Reason: See the way we handle COMM_FAILURES in 
        // ClientRequestDispatcher.createRequest, v1.32

	if (cachedEffectiveTargetObject == null) {
	    CorbaContactInfo corbaContactInfo = (CorbaContactInfo)
		messageMediator.getContactInfo();
	    // REVISIT - get through chain like getLocatedIOR helper below.
	    cachedEffectiveTargetObject =
		iorToObject(corbaContactInfo.getEffectiveTargetIOR());
	}
	return cachedEffectiveTargetObject;
    
public org.omg.CORBA.TypeCode[]exceptions()
See RequestInfoImpl for javadoc.

        checkAccess( MID_EXCEPTIONS );

	if( cachedExceptions == null ) {
	    if( request == null ) {
	       throw stdWrapper.piOperationNotSupported2() ;
	    }

	    // Get the list of exceptions from DII request data, If there are
	    // no exceptions raised then this method will return null.
	    ExceptionList excList = request.exceptions( );
	    int count = excList.count();
	    TypeCode[] excTCList = new TypeCode[count];
	    try {
		for( int i = 0; i < count; i++ ) {
		    excTCList[i] = excList.item( i );
		}
	    } catch( Exception e ) {
		throw wrapper.exceptionInExceptions( e ) ;
	    }

	    cachedExceptions = excTCList;
	}

        // Good citizen: In the interest of efficiency, we assume 
        // interceptors will be "good citizens" in that they will not 
        // modify the contents of the TypeCode[] array.  We also assume 
        // they will not change the values of the containing TypeCodes.

	return cachedExceptions;
    
public org.omg.CORBA.Objectforward_reference()
See RequestInfoImpl for javadoc.

        checkAccess( MID_FORWARD_REFERENCE );
        // Check to make sure we are in LOCATION_FORWARD
        // state as per ptc/00-08-06, table 21-1
        // footnote 2.
        if( replyStatus != LOCATION_FORWARD.value ) {
	    throw stdWrapper.invalidPiCall1() ;
        }

	// Do not cache this value since if an interceptor raises
	// forward request then the next interceptor in the
	// list should see the new value.
	IOR ior = getLocatedIOR();
	return iorToObject(ior);
    
intgetEntryCount()
Retrieve the current entry count

        return this.entryCount;
    
protected booleangetIsOneWay()

	return ! response_expected();
    
private com.sun.corba.se.spi.ior.IORgetLocatedIOR()

	IOR ior;
	CorbaContactInfoList contactInfoList = (CorbaContactInfoList)
	    messageMediator.getContactInfo().getContactInfoList();
	ior = contactInfoList.getEffectiveTargetIOR();
	return ior;
    
booleangetRetryRequest()
Retrieve the current retry request status.

        return this.retryRequest;
    
public org.omg.IOP.TaggedComponentget_effective_component(int id)
Returns the IOP::TaggedComponent with the given ID from the profile selected for this request. IF there is more than one component for a given component ID, it is undefined which component this operation returns (get_effective_component should be called instead).

        checkAccess( MID_GET_EFFECTIVE_COMPONENT );
        
        return get_effective_components( id )[0];
    
public org.omg.IOP.TaggedComponent[]get_effective_components(int id)
Returns all the tagged components with the given ID from the profile selected for this request.

        checkAccess( MID_GET_EFFECTIVE_COMPONENTS );
	Integer integerId = new Integer( id );
	TaggedComponent[] result = null;
	boolean justCreatedCache = false;

	if( cachedEffectiveComponents == null ) {
	    cachedEffectiveComponents = new HashMap();
	    justCreatedCache = true;
	}
	else {
	    // Look in cache:
	    result = (TaggedComponent[])cachedEffectiveComponents.get( 
		integerId );
	}
        
	// null could mean we cached null or not in cache.
	if( (result == null) &&
	    (justCreatedCache ||
	    !cachedEffectiveComponents.containsKey( integerId ) ) )
	{
	    // Not in cache.  Get it from the profile:
	    CorbaContactInfo corbaContactInfo = (CorbaContactInfo)
		messageMediator.getContactInfo();
	    IIOPProfileTemplate ptemp = 
		(IIOPProfileTemplate)corbaContactInfo.getEffectiveProfile().
		getTaggedProfileTemplate();
	    result = ptemp.getIOPComponents(myORB, id);
	    cachedEffectiveComponents.put( integerId, result );
	}
        
        // As per ptc/00-08-06, section 21.3.13.6., If not found, raise 
        // BAD_PARAM with minor code INVALID_COMPONENT_ID.
        if( (result == null) || (result.length == 0) ) {
	    throw stdWrapper.invalidComponentId( integerId ) ;
        }

	// Good citizen: In the interest of efficiency, we will assume 
	// interceptors will not modify the returned TaggedCompoent[], or
	// the TaggedComponents inside of it.  Otherwise, we would need to
	// clone the array and make a deep copy of its contents.
        
        return result;
    
public org.omg.IOP.ServiceContextget_reply_service_context(int id)
does not contain an etry for that ID, BAD_PARAM with a minor code of TBD_BP is raised.

        checkAccess( MID_GET_REPLY_SERVICE_CONTEXT );       

	if( cachedReplyServiceContexts == null ) {
	    cachedReplyServiceContexts = new HashMap();
	}

	// In the event this is called from a oneway, we will have no
	// response object.
	//
	// In the event this is called after a IIOPConnection.purgeCalls,
	// we will have a response object, but that object will
	// not contain a header (which would hold the service context
	// container).  See bug 4624102.
	//
	// REVISIT: this is the only thing used
	// from response at this time.  However, a more general solution
	// would avoid accessing other parts of response's header.
	//
	// Instead of throwing a NullPointer, we will
	// "gracefully" handle these with a BAD_PARAM with minor code 25.

	try {
	    ServiceContexts serviceContexts =
		messageMediator.getReplyServiceContexts();
	    if (serviceContexts == null) {
		throw new NullPointerException();
	    }
	    return getServiceContext(cachedReplyServiceContexts,
				     serviceContexts, id);
	} catch (NullPointerException e) {
	    // REVISIT how this is programmed - not what it does.
	    // See purge calls test.  The waiter is woken up by the
	    // call to purge calls - but there is no reply containing
	    // service contexts.
	    throw stdWrapper.invalidServiceContextId( e ) ;
	}
    
public org.omg.CORBA.Policyget_request_policy(int type)
Returns the given policy in effect for this operation.

        checkAccess( MID_GET_REQUEST_POLICY );
	// _REVISIT_ Our ORB is not policy-based at this time.
	throw wrapper.piOrbNotPolicyBased() ;
    
public org.omg.IOP.ServiceContextget_request_service_context(int id)
See RequestInfoImpl for javadoc.

        checkAccess( MID_GET_REQUEST_SERVICE_CONTEXT );

	if( cachedRequestServiceContexts == null ) {
	    cachedRequestServiceContexts = new HashMap();
	}

	return  getServiceContext(cachedRequestServiceContexts, 
				  messageMediator.getRequestServiceContexts(),
				  id);
    
voidincrementEntryCount()
Increases the entry count by 1.

        this.entryCount++;
    
protected booleanisDIIInitiate()
See comment for setDIIInitiate

	return this.diiInitiate;
    
protected booleanisPICurrentPushed()

	return this.piCurrentPushed;
    
public java.lang.Stringoperation()
See RequestInfoImpl for javadoc.

        // access is currently valid for all states:
        //checkAccess( MID_OPERATION );
	return messageMediator.getOperationName();
    
public java.lang.String[]operation_context()
See RequestInfoImpl for javadoc.

        checkAccess( MID_OPERATION_CONTEXT );

	if( cachedOperationContext == null ) {
	    if( request == null ) {
		throw stdWrapper.piOperationNotSupported4() ;
	    }

	    // Get the list of contexts from DII request data, If there are
	    // no contexts then this method will return null.
	    Context ctx = request.ctx( );
	    // _REVISIT_ The API for get_values is not compliant with the spec,
	    // Revisit this code once it's fixed.
	    // _REVISIT_ Our ORB doesn't support Operation Context, This code
	    // will not be excerscised until it's supported.
	    // The first parameter in get_values is the start_scope which 
	    // if blank makes it as a global scope.
	    // The second parameter is op_flags which is set to RESTRICT_SCOPE
	    // As there is only one defined in the spec.
	    // The Third param is the pattern which is '*' requiring it to 
	    // get all the contexts.
	    NVList nvList = ctx.get_values( "", CTX_RESTRICT_SCOPE.value,"*" );
	    String[] context = new String[(nvList.count() * 2) ];
	    if( ( nvList != null ) &&( nvList.count() != 0 ) ) {
		// The String[] array will contain Name and Value for each
		// context and hence double the size in the array.
		int index = 0;
		for( int i = 0; i < nvList.count(); i++ ) {
		    NamedValue nv;
		    try {
			nv = nvList.item( i );
		    }
		    catch (Exception e ) {
			return (String[]) null;
		    }
		    context[index] = nv.name();
		    index++;
		    context[index] = nv.value().extract_string();
		    index++;
		}
	    }

	    cachedOperationContext = context;
	}

        // Good citizen: In the interest of efficiency, we assume 
        // interceptors will be "good citizens" in that they will not 
        // modify the contents of the String[] array.  

	return cachedOperationContext;
    
public org.omg.CORBA.Anyreceived_exception()
Contains the exception to be returned to the client.

        checkAccess( MID_RECEIVED_EXCEPTION );

	if( cachedReceivedException == null ) {
	    cachedReceivedException = exceptionToAny( exception );
	}

	// Good citizen: In the interest of efficiency, we assume interceptors
	// will not modify the returned Any in any way so we need
	// not make a deep copy of it.

	return cachedReceivedException;
    
public java.lang.Stringreceived_exception_id()
The CORBA::RepositoryId of the exception to be returned to the client.

        checkAccess( MID_RECEIVED_EXCEPTION_ID );

	if( cachedReceivedExceptionId == null ) {
	    String result = null;
	    
	    if( exception == null ) {
		// Note: exception should never be null here since we will 
		// throw a BAD_INV_ORDER if this is not called from 
		// receive_exception.
		throw wrapper.exceptionWasNull() ;
	    } else if( exception instanceof SystemException ) {
		String name = exception.getClass().getName();
		result = ORBUtility.repositoryIdOf(name);
	    } else if( exception instanceof ApplicationException ) {
		result = ((ApplicationException)exception).getId();
	    }

	    // _REVISIT_ We need to be able to handle a UserException in the 
	    // DII case.  How do we extract the ID from a UserException?
	    
	    cachedReceivedExceptionId = result;
	}

	return cachedReceivedExceptionId;
    
public intrequest_id()
See RequestInfoImpl for javadoc.

        // access is currently valid for all states:
        //checkAccess( MID_REQUEST_ID );
	/* 
	 * NOTE: The requestId in client interceptors is the same as the
	 * GIOP request id.  This works because both interceptors and
	 * request ids are scoped by the ORB on the client side.
	 */
	return messageMediator.getRequestId();
    
voidreset()
Reset the info object so that it can be reused for a retry, for example.

    
    //////////////////////////////////////////////////////////////////////
    //
    // NOTE: IF AN ATTRIBUTE IS ADDED, PLEASE UPDATE RESET();
    //
    //////////////////////////////////////////////////////////////////////
    
                        
      
        super.reset();

	// Please keep these in the same order that they're declared above.
        
        retryRequest = false;

        // Do not reset entryCount because we need to know when to pop this
        // from the stack.

        request = null;
	diiInitiate = false;
	messageMediator = null;

	// Clear cached attributes:
	cachedTargetObject = null;
	cachedEffectiveTargetObject = null;
	cachedArguments = null;
	cachedExceptions = null;
	cachedContexts = null;
	cachedOperationContext = null;
	cachedReceivedExceptionId = null;
	cachedResult = null;
	cachedReceivedException = null;
	cachedEffectiveProfile = null;
	cachedRequestServiceContexts = null;
	cachedReplyServiceContexts = null;
        cachedEffectiveComponents = null;

	piCurrentPushed = false;

        startingPointCall = CALL_SEND_REQUEST;
        endingPointCall = CALL_RECEIVE_REPLY;

    
public booleanresponse_expected()
See RequestInfoImpl for javadoc.

	// access is currently valid for all states:
	//checkAccess( MID_RESPONSE_EXPECTED );
	return ! messageMediator.isOneWay();
    
public org.omg.CORBA.Anyresult()
See RequestInfoImpl for javadoc.

        checkAccess( MID_RESULT );

	if( cachedResult == null ) {
	    if( request == null ) {
		throw stdWrapper.piOperationNotSupported5() ;
	    }
	    // Get the result from the DII request data.
	    NamedValue nvResult = request.result( );

	    if( nvResult == null ) {
		throw wrapper.piDiiResultIsNull() ;
	    }

	    cachedResult = nvResult.value();
	}

	// Good citizen: In the interest of efficiency, we assume that
	// interceptors will not modify the contents of the result Any.
	// Otherwise, we would need to create a deep copy of the Any.

        return cachedResult;
    
protected voidsetDIIInitiate(boolean diiInitiate)
Keeps track of whether initiate was called for a DII request. The ORB needs to know this so it knows whether to ignore a second call to initiateClientPIRequest or not.

	this.diiInitiate = diiInitiate;
    
protected voidsetDIIRequest(org.omg.CORBA.Request req)
Sets DII request object in the RequestInfoObject.

         request = req;
    
protected voidsetException(java.lang.Exception exception)
Overridden from RequestInfoImpl.

        super.setException( exception );

	// Clear cached values:
	cachedReceivedException = null;
	cachedReceivedExceptionId = null;
    
protected voidsetInfo(com.sun.corba.se.pept.protocol.MessageMediator messageMediator)

	this.messageMediator = (CorbaMessageMediator)messageMediator;
	// REVISIT - so mediator can handle DII in subcontract.
	this.messageMediator.setDIIInfo(request);
    
protected voidsetLocatedIOR(com.sun.corba.se.spi.ior.IOR ior)

	ORB orb = (ORB) messageMediator.getBroker();

	CorbaContactInfoListIterator iterator = (CorbaContactInfoListIterator)
	    ((CorbaInvocationInfo)orb.getInvocationInfo())
	    .getContactInfoListIterator();

	// REVISIT - this most likely causes reportRedirect to happen twice.
	// Once here and once inside the request dispatcher.
	iterator.reportRedirect(
	    (CorbaContactInfo)messageMediator.getContactInfo(),
	    ior);
    
protected voidsetPICurrentPushed(boolean piCurrentPushed)
The PICurrent stack should only be popped if it was pushed. This is generally the case. But exceptions which occur after the stub's entry to _request but before the push end up in _releaseReply which will try to pop unless told not to.

	this.piCurrentPushed = piCurrentPushed;
    
protected voidsetReplyStatus(short replyStatus)
Overridden from RequestInfoImpl. Calls the super class, then sets the ending point call depending on the reply status.

        super.setReplyStatus( replyStatus );
        switch( replyStatus ) {
        case SUCCESSFUL.value:
            endingPointCall = CALL_RECEIVE_REPLY;
            break;
        case SYSTEM_EXCEPTION.value:
        case USER_EXCEPTION.value:
            endingPointCall = CALL_RECEIVE_EXCEPTION;
            break;
        case LOCATION_FORWARD.value:
        case TRANSPORT_RETRY.value:
            endingPointCall = CALL_RECEIVE_OTHER;
            break;
        }
    
voidsetRetryRequest(boolean retryRequest)
Set or reset the retry request flag.

        this.retryRequest = retryRequest;
    
public org.omg.CORBA.Objecttarget()
The object which the client called to perform the operation.

	// access is currently valid for all states:
        //checkAccess( MID_TARGET );
	if (cachedTargetObject == null) {
	    CorbaContactInfo corbaContactInfo = (CorbaContactInfo)
		messageMediator.getContactInfo();
	    cachedTargetObject =
		iorToObject(corbaContactInfo.getTargetIOR());
	}
	return cachedTargetObject;