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

RequestInfoImpl

public abstract class RequestInfoImpl extends LocalObject implements RequestInfo, RequestInfoExt
Implementation of the RequestInfo interface as specified in orbos/99-12-02 section 5.4.1.

Fields Summary
protected ORB
myORB
protected InterceptorsSystemException
wrapper
protected OMGSystemException
stdWrapper
protected int
flowStackIndex
protected int
startingPointCall
protected int
intermediatePointCall
protected int
endingPointCall
protected short
replyStatus
protected static final short
UNINITIALIZED
protected int
currentExecutionPoint
protected static final int
EXECUTION_POINT_STARTING
protected static final int
EXECUTION_POINT_INTERMEDIATE
protected static final int
EXECUTION_POINT_ENDING
protected boolean
alreadyExecuted
protected Connection
connection
protected ServiceContexts
serviceContexts
protected ForwardRequest
forwardRequest
protected IOR
forwardRequestIOR
protected SlotTable
slotTable
protected Exception
exception
protected static final int
MID_REQUEST_ID
protected static final int
MID_OPERATION
protected static final int
MID_ARGUMENTS
protected static final int
MID_EXCEPTIONS
protected static final int
MID_CONTEXTS
protected static final int
MID_OPERATION_CONTEXT
protected static final int
MID_RESULT
protected static final int
MID_RESPONSE_EXPECTED
protected static final int
MID_SYNC_SCOPE
protected static final int
MID_REPLY_STATUS
protected static final int
MID_FORWARD_REFERENCE
protected static final int
MID_GET_SLOT
protected static final int
MID_GET_REQUEST_SERVICE_CONTEXT
protected static final int
MID_GET_REPLY_SERVICE_CONTEXT
protected static final int
MID_RI_LAST
Constructors Summary
public RequestInfoImpl(ORB myORB)
Creates a new RequestInfoImpl object.

    
    /*
     **********************************************************************
     * Public interfaces
     **********************************************************************/
         
              
          
        super();
        
        this.myORB = myORB;
	wrapper = InterceptorsSystemException.get( myORB, 
	    CORBALogDomains.RPC_PROTOCOL ) ;
	stdWrapper = OMGSystemException.get( myORB, 
	    CORBALogDomains.RPC_PROTOCOL ) ;

        // Capture the current TSC and make it the RSC of this request.
        PICurrent current = (PICurrent)(myORB.getPIHandler().getPICurrent());
        slotTable = current.getSlotTable( );
    
Methods Summary
protected voidaddServiceContext(java.util.HashMap cachedServiceContexts, com.sun.corba.se.spi.servicecontext.ServiceContexts serviceContexts, org.omg.IOP.ServiceContext service_context, boolean replace)
Utility method to add an IOP.ServiceContext to a core.ServiceContexts object. If replace is true, any service context with the given id is replaced.

Raises BAD_INV_ORDER if replace is false and a service context with the given id already exists.

Uses the given HashMap as a cache. If a service context is placed in the container, it goes in the HashMap as well.

	int id = 0 ;
	// Convert IOP.service_context to core.ServiceContext:
	EncapsOutputStream outputStream = new EncapsOutputStream(
	    myORB );
	InputStream inputStream = null;
	UnknownServiceContext coreServiceContext = null;
	ServiceContextHelper.write( outputStream, service_context );
	inputStream = outputStream.create_input_stream();

	// Constructor expects id to already have been read from stream.
	coreServiceContext = new UnknownServiceContext(
	    inputStream.read_long(),
	    (org.omg.CORBA_2_3.portable.InputStream)inputStream );

	id = coreServiceContext.getId();

	if (serviceContexts.get(id) != null)
	    if (replace)
		serviceContexts.delete( id );
	    else 
		throw stdWrapper.serviceContextAddFailed( new Integer(id) ) ;

	serviceContexts.put( coreServiceContext );

	// Place IOP.ServiceContext in cache as well:
	cachedServiceContexts.put( new Integer( id ), service_context );
    
public abstract org.omg.Dynamic.Parameter[]arguments()
This method returns the list of arguments for the operation that was invoked. It raises NO_RESOURCES exception if the operation is not invoked by using DII mechanism.

protected abstract voidcheckAccess(int methodID)
Check whether the caller is allowed to access this method at this particular time. This is overridden in subclasses to implement the validity table specified in ptc/00-04-05, table 21-1 and 21-2. The currentExecutionPoint attribute is checked, and if access is forbidden at this time, BAD_INV_ORDER is raised with a minor code of TBD_BIO.

param
methodID The ID of this method, one of the MID_* constants. This allows us to easily look up the method access in a table. Note that method ids may overlap between subclasses.

public com.sun.corba.se.spi.legacy.connection.Connectionconnection()

return
The connection on which the request is made. Note: we store the connection as an internal type but expose it here as an external type.

	return connection;
    
public abstract java.lang.String[]contexts()
This method returns the list of contexts for the DII operation. It raises NO_RESOURCES exception if the operation is not invoked by using DII mechanism.

protected org.omg.CORBA.AnyexceptionToAny(java.lang.Exception exception)
Utility to wrap the given Exception in an Any object and return it. If the exception is a UserException which cannot be inserted into an any, then this returns an Any containing the system exception UNKNOWN.

        Any result = myORB.create_any();

        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.exceptionWasNull2() ;
        } else if( exception instanceof SystemException ) {
            ORBUtility.insertSystemException(
                (SystemException)exception, result );
        } else if( exception instanceof ApplicationException ) {
            // Use the Helper class for this exception to insert it into an
            // Any.
            try {
                // Insert the user exception inside the application exception
                // into the Any result:
                ApplicationException appException =
                    (ApplicationException)exception;
                insertApplicationException( appException, result );
            } catch( UNKNOWN e ) {
                // As per ptc/00-08-06, 21.3.13.4. if we cannot find the
                // appropriate class, then return an any containing UNKNOWN,
                // with a minor code of 1.  This is conveniently the same
                // exception that is returned from the 
		// insertApplicationException utility method.
                ORBUtility.insertSystemException( e, result );
            }
        } else if( exception instanceof UserException ) {
	    try {
		UserException userException = (UserException)exception;
		insertUserException( userException, result );
	    } catch( UNKNOWN e ) {
                ORBUtility.insertSystemException( e, result );
	    }
	}


        return result;
    
public abstract org.omg.CORBA.TypeCode[]exceptions()
This method returns the list of exceptios that was raised when the operation was invoked. It raises NO_RESOURCES exception if the operation is not invoked by using DII mechanism.

public abstract org.omg.CORBA.Objectforward_reference()
Implementation for forward_reference() differs for client and server implementations. If the reply_status attribute is LOCATION_FORWARD then this attribute will contain the object to which the request will be forwarded. It is indeterminate whether a forwarded request will actually occur.

protected booleangetAlreadyExecuted()
Returns true if all interceptors' starting and ending points have already executed to completion, or false if not yet.

        return this.alreadyExecuted;
    
protected intgetEndingPointCall()
Retrieves the current ending point call type (see setEndingPointCall for more details).

        return this.endingPointCall;
    
java.lang.ExceptiongetException()
Returns the exception to be returned by received_exception and received_exception_id.

        return this.exception;
    
protected intgetFlowStackIndex()
Returns the number of interceptors whose starting interception points were actually invoked on this client request. See setFlowStackIndex for more details.

        return this.flowStackIndex;
    
protected org.omg.PortableInterceptor.ForwardRequestgetForwardRequestException()
Retrieves the ForwardRequest object as a ForwardRequest exception.

	if( this.forwardRequest == null ) {
	    if( this.forwardRequestIOR != null ) {
		// Convert the internal IOR to a forward request exception
		// by creating an object reference.
		org.omg.CORBA.Object obj = iorToObject(this.forwardRequestIOR);
		this.forwardRequest = new ForwardRequest( obj );
	    }
	}

        return this.forwardRequest;
    
protected com.sun.corba.se.spi.ior.IORgetForwardRequestIOR()
Retrieves the IOR of the ForwardRequest exception.

	if( this.forwardRequestIOR == null ) {
	    if( this.forwardRequest != null ) {
		this.forwardRequestIOR = ORBUtility.getIOR(
		    this.forwardRequest.forward ) ;
	    }
	}

	return this.forwardRequestIOR;
    
protected intgetIntermediatePointCall()
Retrieves the current intermediate point call type (see setEndingPointCall for more details).

        return this.intermediatePointCall;
    
protected shortgetReplyStatus()
Gets the current reply_status without doing an access check (available only to package and subclasses)

        return this.replyStatus;
    
protected org.omg.IOP.ServiceContextgetServiceContext(java.util.HashMap cachedServiceContexts, com.sun.corba.se.spi.servicecontext.ServiceContexts serviceContexts, int id)
Utility method to look up a service context with the given id and convert it to an IOP.ServiceContext. Uses the given HashMap as a cache. If not found in cache, the result is inserted in the cache.

        org.omg.IOP.ServiceContext result = null;
        Integer integerId = new Integer( id );

	// Search cache first:
        result = (org.omg.IOP.ServiceContext)
	    cachedServiceContexts.get( integerId );

	// null could normally mean that either we cached the value null 
	// or it's not in the cache.  However, there is no way for us to 
	// cache the value null in the following code.
        if( result == null ) {
	    // Not in cache.  Find it and put in cache.
	    // Get the desired "core" service context.
	    com.sun.corba.se.spi.servicecontext.ServiceContext context = 
		serviceContexts.get( id );
	    if (context == null)
		throw stdWrapper.invalidServiceContextId() ;

	    // Convert the "core" service context to an 
	    // "IOP" ServiceContext by writing it to a 
	    // CDROutputStream and reading it back.
	    EncapsOutputStream out = new EncapsOutputStream(myORB);

	    context.write( out, GIOPVersion.V1_2 );
	    InputStream inputStream = out.create_input_stream();
	    result = ServiceContextHelper.read( inputStream );

	    cachedServiceContexts.put( integerId, result );
	}

	// Good citizen: For increased efficiency, we assume that interceptors
	// will not modify the returned ServiceContext.  Otherwise, we would
	// have to make a deep copy.

        return result;
    
protected intgetStartingPointCall()
Retrieves the current starting point call type (see setStartingPointCall for more details).

        return this.startingPointCall;
    
public abstract org.omg.IOP.ServiceContextget_reply_service_context(int id)
Implementation for get_reply_service_context() differs for client and server implementations. This operation returns a copy of the service context with the given ID that is associated with the reply. IF the request's service context does not contain an entry for that ID, BAD_PARAM with a minor code of TBD_BP is raised.

public abstract org.omg.IOP.ServiceContextget_request_service_context(int id)
Implementation for get_request_service_context() differs for client and server implementations. This operation returns a copy of the service context with the given ID that is associated with the request. If the request's service context does not contain an etry for that ID, BAD_PARAM with a minor code of TBD_BP is raised.

public org.omg.CORBA.Anyget_slot(int id)
Returns the data from the given slot of the PortableInterceptor::Current that is in the scope of the request.

If the given slot has not been set, then an any containing a type code with a TCKind value of tk_null is returned.

If the ID does not define an allocated slot, InvalidSlot is raised.

	// access is currently valid for all states:
        //checkAccess( MID_GET_SLOT );
        // Delegate the call to the slotTable which was set when RequestInfo was
        // created.
        return slotTable.get_slot( id );
    
private voidinsertApplicationException(org.omg.CORBA.portable.ApplicationException appException, org.omg.CORBA.Any result)
Inserts the UserException inside the given ApplicationException into the given Any. Throws an UNKNOWN with minor code OMGSYstemException.UNKNOWN_USER_EXCEPTION if the Helper class could not be found to insert it with.

        try {
            // Extract the UserException from the ApplicationException.
            // Look up class name from repository id:
            RepositoryId repId = RepositoryId.cache.getId(
                appException.getId() );
            String className = repId.getClassName();
           
            // Find the read method on the helper class:
            String helperClassName = className + "Helper";
            Class helperClass = ORBClassLoader.loadClass( helperClassName );
            Class[] readParams = new Class[1];
            readParams[0] = org.omg.CORBA.portable.InputStream.class;
            Method readMethod = helperClass.getMethod( "read", readParams );
           
            // Invoke the read method, passing in the input stream to
            // retrieve the user exception.  Mark and reset the stream
            // as to not disturb it.
            InputStream ueInputStream = appException.getInputStream();
            ueInputStream.mark( 0 );
            UserException userException = null;
            try {
                java.lang.Object[] readArguments = new java.lang.Object[1];
                readArguments[0] = ueInputStream;
                userException = (UserException)readMethod.invoke(
                    null, readArguments );
            }
            finally {
                try {
                    ueInputStream.reset();
                }
                catch( IOException e ) {
		    throw wrapper.markAndResetFailed( e ) ;
                }
            }

            // Insert this UserException into the provided Any using the
            // helper class.
	    insertUserException( userException, result );
        } catch( ClassNotFoundException e ) {
	    throw stdWrapper.unknownUserException( CompletionStatus.COMPLETED_MAYBE, e ) ;
        } catch( NoSuchMethodException e ) {
	    throw stdWrapper.unknownUserException( CompletionStatus.COMPLETED_MAYBE, e ) ;
        } catch( SecurityException e ) {
	    throw stdWrapper.unknownUserException( CompletionStatus.COMPLETED_MAYBE, e ) ;
        } catch( IllegalAccessException e ) {
	    throw stdWrapper.unknownUserException( CompletionStatus.COMPLETED_MAYBE, e ) ;
        } catch( IllegalArgumentException e ) {
	    throw stdWrapper.unknownUserException( CompletionStatus.COMPLETED_MAYBE, e ) ;
        } catch( InvocationTargetException e ) {
	    throw stdWrapper.unknownUserException( CompletionStatus.COMPLETED_MAYBE, e ) ;
        }
    
private voidinsertUserException(org.omg.CORBA.UserException userException, org.omg.CORBA.Any result)
Inserts the UserException into the given Any. Throws an UNKNOWN with minor code OMGSYstemException.UNKNOWN_USER_EXCEPTION if the Helper class could not be found to insert it with.

        try {
            // Insert this UserException into the provided Any using the
            // helper class.
            if( userException != null ) {
		Class exceptionClass = userException.getClass();
		String className = exceptionClass.getName();
		String helperClassName = className + "Helper";
		Class helperClass = ORBClassLoader.loadClass( helperClassName );
           
                // Find insert( Any, class ) method
                Class[] insertMethodParams = new Class[2];
                insertMethodParams[0] = org.omg.CORBA.Any.class;
                insertMethodParams[1] = exceptionClass;
                Method insertMethod = helperClass.getMethod(
                    "insert", insertMethodParams );

                // Call helper.insert( result, userException ):
                java.lang.Object[] insertMethodArguments =
                    new java.lang.Object[2];
                insertMethodArguments[0] = result;
                insertMethodArguments[1] = userException;
                insertMethod.invoke( null, insertMethodArguments );
            }
        } catch( ClassNotFoundException e ) {
	    throw stdWrapper.unknownUserException( CompletionStatus.COMPLETED_MAYBE, e );
        } catch( NoSuchMethodException e ) {
	    throw stdWrapper.unknownUserException( CompletionStatus.COMPLETED_MAYBE, e );
        } catch( SecurityException e ) {
	    throw stdWrapper.unknownUserException( CompletionStatus.COMPLETED_MAYBE, e );
        } catch( IllegalAccessException e ) {
	    throw stdWrapper.unknownUserException( CompletionStatus.COMPLETED_MAYBE, e );
        } catch( IllegalArgumentException e ) {
	    throw stdWrapper.unknownUserException( CompletionStatus.COMPLETED_MAYBE, e );
        } catch( InvocationTargetException e ) {
	    throw stdWrapper.unknownUserException( CompletionStatus.COMPLETED_MAYBE, e );
        } 
    
protected org.omg.CORBA.ObjectiorToObject(com.sun.corba.se.spi.ior.IOR ior)

	return ORBUtility.makeObjectReference( ior ) ;
    
protected org.omg.Dynamic.Parameter[]nvListToParameterArray(org.omg.CORBA.NVList parNVList)
Internal utility method to convert an NVList into a PI Parameter[]


	// _REVISIT_ This utility method should probably be doing a deep
	// copy so interceptor can't accidentally change the arguments.

        int count = parNVList.count();
        Parameter[] plist = new Parameter[count];
        try {
            for( int i = 0; i < count; i++ ) {
                Parameter p = new Parameter();
                plist[i] = p;
                NamedValue nv = parNVList.item( i );
                plist[i].argument = nv.value();
                // ParameterMode spec can be found in 99-10-07.pdf
                // Section:10.5.22
                // nv.flags spec can be found in 99-10-07.pdf
                // Section 7.1.1
                // nv.flags has ARG_IN as 1, ARG_OUT as 2 and ARG_INOUT as 3
                // To convert this into enum PARAM_IN, PARAM_OUT and
                // PARAM_INOUT the value is subtracted by 1.
                plist[i].mode = ParameterMode.from_int( nv.flags() - 1 );
            }
        } catch ( Exception e ) {
	    throw wrapper.exceptionInArguments( e ) ;
        }

        return plist;
    
public abstract java.lang.Stringoperation()
Implementation for operation() differs for client and server implementations. The name of the operation being invoked.

public abstract java.lang.String[]operation_context()
This method returns the list of operation_context for the DII operation. It raises NO_RESOURCES exception if the operation is not invoked by using DII mechanism.

public shortreply_status()
Describes the state of the result of the operation invocation. Its value can be one of the following:
  • PortableInterceptor::SUCCESSFUL
  • PortableInterceptor::SYSTEM_EXCEPTION
  • PortableInterceptor::USER_EXCEPTION
  • PortableInterceptor::LOCATION_FORWARD
  • PortableInterceptor::TRANSPORT_RETRY

        checkAccess( MID_REPLY_STATUS );
        return replyStatus;
    
public abstract intrequest_id()
Implementation for request_id() differs for client and server implementations. Uniquely identifies an active request/reply sequence. Once a request/reply sequence is concluded this ID may be reused. (this is NOT necessarily the same as the GIOP request_id).

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();
    //
    //////////////////////////////////////////////////////////////////////
    
                        
      

	// Please keep these in the same order as declared above.

        flowStackIndex = 0;
        startingPointCall = 0;
        intermediatePointCall = 0;
        endingPointCall = 0;
        replyStatus = UNINITIALIZED;
        currentExecutionPoint = EXECUTION_POINT_STARTING;
        alreadyExecuted = false;
	connection = null;
        serviceContexts = null;
        forwardRequest = null;
	forwardRequestIOR = null;
        exception = null;

        // We don't need to reset the Slots because they are
        // already in the clean state after recieve_<point> interceptor
        // are called. 
    
public abstract booleanresponse_expected()
Implementation for response_expected() differs for client and server implementations. Indicates whether a response is expected. On the client, a reply is not returned when response_expected is false, so receive_reply cannot be called. receive_other is called unless an exception occurs, in which case receive_exception is called. On the client, within send_poll, this attribute is true.

public abstract org.omg.CORBA.Anyresult()
This method returns the result from the invoked DII operation. It raises NO_RESOURCES exception if the operation is not invoked by using DII mechanism.

protected voidsetAlreadyExecuted(boolean alreadyExecuted)
Sets whether all interceotrs' starting and ending points have already been executed to completion.

        this.alreadyExecuted = alreadyExecuted;
    
protected voidsetCurrentExecutionPoint(int executionPoint)
Sets the execution point that we are currently executing (starting points, intermediate points, or ending points). This allows us to enforce the validity table.

        this.currentExecutionPoint = executionPoint;
    
protected voidsetEndingPointCall(int call)
Sets which ending interception point should be called for each interceptor in the virtual flow stack.

        this.endingPointCall = call;
    
protected voidsetException(java.lang.Exception exception)
Sets the exception to be returned by received_exception and received_exception_id.

        this.exception = exception;
    
protected voidsetFlowStackIndex(int num)
Sets the number of interceptors whose starting interception points were successfully invoked on this client call. As specified in orbos/99-12-02, section 5.2.1., not all interceptors will be invoked if a ForwardRequest exception or a system exception is raised. This keeps track of how many were successfully executed so we know not to execute the corresponding ending interception points for the interceptors whose starting interception points were not completed. This simulates the "Flow Stack Visual Model" presented in section 5.1.3.

        this.flowStackIndex = num;
    
protected voidsetForwardRequest(org.omg.PortableInterceptor.ForwardRequest forwardRequest)
Stores the given ForwardRequest object for later analysis. This version supplements setForwardRequest( IOR );

        this.forwardRequest = forwardRequest;
	this.forwardRequestIOR = null;
    
protected voidsetForwardRequest(com.sun.corba.se.spi.ior.IOR ior)
Stores the given IOR for later forward request analysis. This version supplements setForwardRequest( ForwardRequest );

	this.forwardRequestIOR = ior;
	this.forwardRequest = null;
    
protected voidsetIntermediatePointCall(int call)
Sets which intermediate interception point should be called for each interceptor in the virtual flow stack.

        this.intermediatePointCall = call;
    
protected voidsetReplyStatus(short replyStatus)
Sets the value to be returned by reply_status

        this.replyStatus = replyStatus;
    
voidsetSlotTable(com.sun.corba.se.impl.interceptors.SlotTable slotTable)
The server side does an explicit set rather than taking the current PICurrent table as is done in the general RequestInfoImpl constructor.

	this.slotTable = slotTable;
    
protected voidsetStartingPointCall(int call)
Sets which starting interception point should be called for each interceptor in the virtual flow stack.

        this.startingPointCall = call;
    
public shortsync_scope()
Defined in the Messaging specification. Pertinent only when response_expected is false. If response_expected is true, the value of sync_scope is undefined. It defines how far the request shall progress before control is returned to the client. This attribute may have one of the follwing values:
  • Messaging::SYNC_NONE
  • Messaging::SYNC_WITH_TRANSPORT
  • Messaging::SYNC_WITH_SERVER
  • Messaging::SYNC_WITH_TARGET

        checkAccess( MID_SYNC_SCOPE );
        return SYNC_WITH_TRANSPORT.value; // REVISIT - get from MessageMediator