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

InterceptorInvoker

public class InterceptorInvoker extends Object
Handles invocation of interceptors. Has specific knowledge of how to invoke IOR, ClientRequest, and ServerRequest interceptors. Makes use of the InterceptorList to retrieve the list of interceptors to be invoked. Most methods in this class are package scope so that they may only be called from the PIHandlerImpl.

Fields Summary
private com.sun.corba.se.spi.orb.ORB
orb
private InterceptorList
interceptorList
private boolean
enabled
private PICurrent
current
Constructors Summary
InterceptorInvoker(com.sun.corba.se.spi.orb.ORB orb, InterceptorList interceptorList, PICurrent piCurrent)
Creates a new Interceptor Invoker. Constructor is package scope so only the ORB can create it. The invoker is initially disabled, and must be explicitly enabled using setEnabled().


    // NOTE: Be careful about adding additional attributes to this class.  
    // Multiple threads may be calling methods on this invoker at the same 
    // time.

                                       
         
                           
    
        this.orb = orb;
	this.interceptorList = interceptorList;
	this.enabled = false;
        this.current = piCurrent;
    
Methods Summary
voidadapterManagerStateChanged(int managerId, short newState)

	if (enabled) {
	    IORInterceptor[] interceptors = 
                (IORInterceptor[])interceptorList.getInterceptors( 
                InterceptorList.INTERCEPTOR_TYPE_IOR );
	    int size = interceptors.length;

	    for( int i = (size - 1); i >= 0; i-- ) {
		try {
		    IORInterceptor interceptor = interceptors[i];
		    if (interceptor instanceof IORInterceptor_3_0) {
			IORInterceptor_3_0 interceptor30 = (IORInterceptor_3_0)interceptor ;
			interceptor30.adapter_manager_state_changed( managerId, 
			    newState );
		    }
		} catch (Exception exc) {
		    // No-op: ignore exception in this case
		}
	    }
	}
    
voidadapterStateChanged(org.omg.PortableInterceptor.ObjectReferenceTemplate[] templates, short newState)

	if (enabled) {
	    IORInterceptor[] interceptors = 
                (IORInterceptor[])interceptorList.getInterceptors( 
                InterceptorList.INTERCEPTOR_TYPE_IOR );
	    int size = interceptors.length;

	    for( int i = (size - 1); i >= 0; i-- ) {
		try {
		    IORInterceptor interceptor = interceptors[i];
		    if (interceptor instanceof IORInterceptor_3_0) {
			IORInterceptor_3_0 interceptor30 = (IORInterceptor_3_0)interceptor ;
			interceptor30.adapter_state_changed( templates, newState );
		    }
		} catch (Exception exc) {
		    // No-op: ignore exception in this case
		}
	    }
	}
    
voidinvokeClientInterceptorEndingPoint(ClientRequestInfoImpl info)
Invokes either receive_reply, receive_exception, or receive_other, depending on the value of info.getEndingPointCall()

	// If invocation is not yet enabled, don't do anything.
	if( enabled ) {
	    try {
		// NOTE: It is assumed someplace else prepared a
		// fresh TSC slot table.

		info.setCurrentExecutionPoint( info.EXECUTION_POINT_ENDING );
		
		// Get all ClientRequestInterceptors:
		ClientRequestInterceptor[] clientInterceptors = 
		    (ClientRequestInterceptor[])interceptorList.
		    getInterceptors( InterceptorList.INTERCEPTOR_TYPE_CLIENT );
		int flowStackIndex = info.getFlowStackIndex();
		
		// Determine whether we are calling receive_reply, 
		// receive_exception, or receive_other:
		int endingPointCall = info.getEndingPointCall();

		// If we would be calling RECEIVE_REPLY, but this is a 
		// one-way call, override this and call receive_other:
		if( ( endingPointCall == 
		      ClientRequestInfoImpl.CALL_RECEIVE_REPLY ) &&
		    info.getIsOneWay() )
		{
		    endingPointCall = ClientRequestInfoImpl.CALL_RECEIVE_OTHER;
		    info.setEndingPointCall( endingPointCall );
		}
		
		// Only step through the interceptors whose starting points
		// have successfully returned.
		// Unlike the previous loop, this one counts backwards for a 
		// reason - we must execute these in the reverse order of the
		// starting points.
		for( int i = (flowStackIndex - 1); i >= 0; i-- ) {
		    
		    try {
			switch( endingPointCall ) {
			case ClientRequestInfoImpl.CALL_RECEIVE_REPLY:
			    clientInterceptors[i].receive_reply( info );
			    break;
			case ClientRequestInfoImpl.CALL_RECEIVE_EXCEPTION:
			    clientInterceptors[i].receive_exception( info );
			    break;
			case ClientRequestInfoImpl.CALL_RECEIVE_OTHER:
			    clientInterceptors[i].receive_other( info );
			    break;
			}
		    }
		    catch( ForwardRequest e ) {

			// as per PI spec (orbos/99-12-02 sec 5.2.1.), if
			// interception point throws a ForwardException, 
			// ending point call changes to receive_other.
			endingPointCall = 
			    ClientRequestInfoImpl.CALL_RECEIVE_OTHER;
			info.setEndingPointCall( endingPointCall );
			info.setReplyStatus( LOCATION_FORWARD.value );
			info.setForwardRequest( e );
			updateClientRequestDispatcherForward( info );
		    }
		    catch( SystemException e ) {

			// as per PI spec (orbos/99-12-02 sec 5.2.1.), if
			// interception point throws a SystemException, 
			// ending point call changes to receive_exception.
			endingPointCall = 
			    ClientRequestInfoImpl.CALL_RECEIVE_EXCEPTION;
			info.setEndingPointCall( endingPointCall );
			info.setReplyStatus( SYSTEM_EXCEPTION.value );
			info.setException( e );
		    } 
		}
	    }
	    finally {
		// See doc for setPICurrentPushed as to why this is necessary.
		// Check info for null in case errors happen before initiate.
		if (info != null && info.isPICurrentPushed()) {
		    current.popSlotTable( );
		    // After the pop, original client's TSC slot table
		    // remains avaiable via PICurrent.
		}
	    }
        } // end enabled check
    
voidinvokeClientInterceptorStartingPoint(ClientRequestInfoImpl info)
Invokes either send_request, or send_poll, depending on the value of info.getStartingPointCall()

	// If invocation is not yet enabled, don't do anything.
	if( enabled ) {
	    try {
		// Make a a fresh slot table available to TSC in case
		// interceptors need to make out calls.
		// Client's TSC is now RSC via RequestInfo.
		current.pushSlotTable( );
		info.setPICurrentPushed( true );
		info.setCurrentExecutionPoint( info.EXECUTION_POINT_STARTING );
		
		// Get all ClientRequestInterceptors:
		ClientRequestInterceptor[] clientInterceptors = 
		    (ClientRequestInterceptor[])interceptorList.
		    getInterceptors( InterceptorList.INTERCEPTOR_TYPE_CLIENT );
		int size = clientInterceptors.length;

		// We will assume that all interceptors returned successfully,
		// and adjust the flowStackIndex to the appropriate value if
		// we later discover otherwise.
		int flowStackIndex = size;
		boolean continueProcessing = true;
	
		// Determine whether we are calling send_request or send_poll:
		// (This is currently commented out because our ORB does not 
		// yet support the Messaging specification, so send_poll will
		// never occur.  Once we have implemented messaging, this may
		// be uncommented.)
		// int startingPointCall = info.getStartingPointCall();
		for( int i = 0; continueProcessing && (i < size); i++ ) {
		    try {
			clientInterceptors[i].send_request( info );
			
			// Again, it is not necessary for a switch here, since
			// there is only one starting point call type (see
			// above comment).
			
			//switch( startingPointCall ) {
			//case ClientRequestInfoImpl.CALL_SEND_REQUEST:
			    //clientInterceptors[i].send_request( info );
			    //break;
			//case ClientRequestInfoImpl.CALL_SEND_POLL:
			    //clientInterceptors[i].send_poll( info );
			    //break;
			//}

		    }
		    catch( ForwardRequest e ) {
			// as per PI spec (orbos/99-12-02 sec 5.2.1.), if
			// interception point throws a ForwardRequest, 
			// no other Interceptors' send_request operations are 
			// called.
			flowStackIndex = i;
			info.setForwardRequest( e );
			info.setEndingPointCall( 
			    ClientRequestInfoImpl.CALL_RECEIVE_OTHER );
			info.setReplyStatus( LOCATION_FORWARD.value );
			
			updateClientRequestDispatcherForward( info );
			
			// For some reason, using break here causes the VM on 
			// NT to lose track of the value of flowStackIndex 
			// after exiting the for loop.  I changed this to 
			// check a boolean value instead and it seems to work 
			// fine.
			continueProcessing = false;
		    }
		    catch( SystemException e ) {
			// as per PI spec (orbos/99-12-02 sec 5.2.1.), if
			// interception point throws a SystemException, 
			// no other Interceptors' send_request operations are 
			// called.
			flowStackIndex = i;
			info.setEndingPointCall( 
			    ClientRequestInfoImpl.CALL_RECEIVE_EXCEPTION );
			info.setReplyStatus( SYSTEM_EXCEPTION.value );
			info.setException( e );

			// For some reason, using break here causes the VM on 
			// NT to lose track of the value of flowStackIndex 
			// after exiting the for loop.  I changed this to 
			// check a boolean value instead and it seems to 
			// work fine.
			continueProcessing = false;
		    } 
		}
		
		// Remember where we left off in the flow stack:
		info.setFlowStackIndex( flowStackIndex );
	    }
	    finally {
		// Make the SlotTable fresh for the next interception point.
		current.resetSlotTable( );
	    }
        } // end enabled check
    
voidinvokeServerInterceptorEndingPoint(ServerRequestInfoImpl info)
Invokes either send_reply, send_exception, or send_other, depending on the value of info.getEndingPointCall()

	// If invocation is not yet enabled, don't do anything.
	if( enabled ) {
	    try {
		// NOTE: do not touch the slotStack.  The RSC and TSC are
		// equivalent at this point.

		// REVISIT: This is moved out to PIHandlerImpl until dispatch
		// path is rearchitected.  It must be there so that
		// it always gets executed so if an interceptor raises
		// an exception any service contexts added in earlier points
		// this point get put in the exception reply (via the SC Q).
		//info.setCurrentExecutionPoint( info.EXECUTION_POINT_ENDING );
		
		// Get all ServerRequestInterceptors:
		ServerRequestInterceptor[] serverInterceptors = 
		    (ServerRequestInterceptor[])interceptorList.
		    getInterceptors( InterceptorList.INTERCEPTOR_TYPE_SERVER );
		int flowStackIndex = info.getFlowStackIndex();
		
		// Determine whether we are calling 
		// send_exception, or send_other:
		int endingPointCall = info.getEndingPointCall();
		
		// Only step through the interceptors whose starting points
		// have successfully returned.
		for( int i = (flowStackIndex - 1); i >= 0; i-- ) {
		    try {
			switch( endingPointCall ) {
			case ServerRequestInfoImpl.CALL_SEND_REPLY:
			    serverInterceptors[i].send_reply( info );
			    break;
			case ServerRequestInfoImpl.CALL_SEND_EXCEPTION:
			    serverInterceptors[i].send_exception( info );
			    break;
			case ServerRequestInfoImpl.CALL_SEND_OTHER:
			    serverInterceptors[i].send_other( info );
			    break;
			}
		    }
		    catch( ForwardRequest e ) {
			// as per PI spec (orbos/99-12-02 sec 5.3.1.), if
			// interception point throws a ForwardException, 
			// ending point call changes to receive_other.
			endingPointCall = 
			    ServerRequestInfoImpl.CALL_SEND_OTHER;
			info.setEndingPointCall( endingPointCall );
			info.setForwardRequest( e );
			info.setReplyStatus( LOCATION_FORWARD.value );
			info.setForwardRequestRaisedInEnding();
		    }
		    catch( SystemException e ) {
			// as per PI spec (orbos/99-12-02 sec 5.3.1.), if
			// interception point throws a SystemException, 
			// ending point call changes to send_exception.
			endingPointCall = 
			    ServerRequestInfoImpl.CALL_SEND_EXCEPTION;
			info.setEndingPointCall( endingPointCall );
			info.setException( e );
			info.setReplyStatus( SYSTEM_EXCEPTION.value );
		    }
		}
		
		// Remember that all interceptors' starting and ending points
		// have already been executed so we need not do anything.
		info.setAlreadyExecuted( true );
	    }
            finally {
		// Get rid of the Server side RSC.
		current.popSlotTable();
	    }
        } // end enabled check
    
voidinvokeServerInterceptorIntermediatePoint(ServerRequestInfoImpl info)
Invokes receive_request interception points

        int intermediatePointCall = info.getIntermediatePointCall();
	// If invocation is not yet enabled, don't do anything.
	if( enabled && ( intermediatePointCall != 
                         ServerRequestInfoImpl.CALL_INTERMEDIATE_NONE ) )
        {
	    // NOTE: do not touch the slotStack.  The RSC and TSC are
	    // equivalent at this point.

            info.setCurrentExecutionPoint( info.EXECUTION_POINT_INTERMEDIATE );
            
            // Get all ServerRequestInterceptors:
            ServerRequestInterceptor[] serverInterceptors = 
                (ServerRequestInterceptor[])
                interceptorList.getInterceptors( 
                InterceptorList.INTERCEPTOR_TYPE_SERVER );
            int size = serverInterceptors.length;

            // Currently, there is only one server-side intermediate point
            // interceptor called receive_request.
            for( int i = 0; i < size; i++ ) {

                try {
                    serverInterceptors[i].receive_request( info );
                }
                catch( ForwardRequest e ) {

                    // as per PI spec (orbos/99-12-02 sec 5.3.1.), if
                    // interception point throws a ForwardRequest, 
                    // no other Interceptors' intermediate points are 
                    // called and send_other is called.
		    info.setForwardRequest( e );
                    info.setEndingPointCall( 
                        ServerRequestInfoImpl.CALL_SEND_OTHER );
                    info.setReplyStatus( LOCATION_FORWARD.value );
                    break;
                }
                catch( SystemException e ) {

                    // as per PI spec (orbos/99-12-02 sec 5.3.1.), if
                    // interception point throws a SystemException, 
                    // no other Interceptors' starting points are 
                    // called.
		    info.setException( e );
                    info.setEndingPointCall( 
                        ServerRequestInfoImpl.CALL_SEND_EXCEPTION );
                    info.setReplyStatus( SYSTEM_EXCEPTION.value );
                    break;
                }
            }
        } // end enabled check
    
voidinvokeServerInterceptorStartingPoint(ServerRequestInfoImpl info)
Invokes receive_request_service_context interception points.

	// If invocation is not yet enabled, don't do anything.
	if( enabled ) {
	    try {
		// Make a fresh slot table for RSC.
		current.pushSlotTable();
		info.setSlotTable(current.getSlotTable());

		// Make a fresh slot table for TSC in case
		// interceptors need to make out calls.
		current.pushSlotTable( );

		info.setCurrentExecutionPoint( info.EXECUTION_POINT_STARTING );
		
		// Get all ServerRequestInterceptors:
		ServerRequestInterceptor[] serverInterceptors = 
		    (ServerRequestInterceptor[])interceptorList.
		    getInterceptors( InterceptorList.INTERCEPTOR_TYPE_SERVER );
		int size = serverInterceptors.length;

		// We will assume that all interceptors returned successfully,
		// and adjust the flowStackIndex to the appropriate value if
		// we later discover otherwise.
		int flowStackIndex = size;
		boolean continueProcessing = true;
		
		// Currently, there is only one server-side starting point
		// interceptor called receive_request_service_contexts.
		for( int i = 0; continueProcessing && (i < size); i++ ) {
		    
		    try {
			serverInterceptors[i].
			    receive_request_service_contexts( info );
		    }
		    catch( ForwardRequest e ) {
			// as per PI spec (orbos/99-12-02 sec 5.3.1.), if
			// interception point throws a ForwardRequest, 
			// no other Interceptors' starting points are 
			// called and send_other is called.
			flowStackIndex = i;
			info.setForwardRequest( e );
			info.setIntermediatePointCall(
			    ServerRequestInfoImpl.CALL_INTERMEDIATE_NONE );
			info.setEndingPointCall( 
			    ServerRequestInfoImpl.CALL_SEND_OTHER );
			info.setReplyStatus( LOCATION_FORWARD.value );

			// For some reason, using break here causes the VM on 
			// NT to lose track of the value of flowStackIndex 
			// after exiting the for loop.  I changed this to 
			// check a boolean value instead and it seems to work 
			// fine.
			continueProcessing = false;
		    }
		    catch( SystemException e ) {

			// as per PI spec (orbos/99-12-02 sec 5.3.1.), if
			// interception point throws a SystemException, 
			// no other Interceptors' starting points are 
			// called.
			flowStackIndex = i;
			info.setException( e );
			info.setIntermediatePointCall(
			    ServerRequestInfoImpl.CALL_INTERMEDIATE_NONE );
			info.setEndingPointCall( 
			    ServerRequestInfoImpl.CALL_SEND_EXCEPTION );
			info.setReplyStatus( SYSTEM_EXCEPTION.value );

			// For some reason, using break here causes the VM on 
			// NT to lose track of the value of flowStackIndex 
			// after exiting the for loop.  I changed this to 
			// check a boolean value instead and it seems to 
			// work fine.
			continueProcessing = false;
		    }
	    
		}
		
		// Remember where we left off in the flow stack:
		info.setFlowStackIndex( flowStackIndex );
	    }
	    finally {
		// The remaining points, ServantManager and Servant
		// all run in the same logical thread.
		current.popSlotTable( );
		// Now TSC and RSC are equivalent.
	    }
        } // end enabled check
    
voidobjectAdapterCreated(com.sun.corba.se.spi.oa.ObjectAdapter oa)
Called when a new POA is created.

param
oa The Object Adapter associated with the IOR interceptor.

	// If invocation is not yet enabled, don't do anything.
	if( enabled ) {
	    // Create IORInfo object to pass to IORInterceptors:
	    IORInfoImpl info = new IORInfoImpl( oa );

	    // Call each IORInterceptor:
	    IORInterceptor[] iorInterceptors = 
                (IORInterceptor[])interceptorList.getInterceptors( 
                InterceptorList.INTERCEPTOR_TYPE_IOR );
	    int size = iorInterceptors.length;

	    // Implementation note:
	    // This loop counts backwards for greater efficiency.
	    // Benchmarks have shown that counting down is more efficient
	    // than counting up in Java for loops, as a compare to zero is
	    // faster than a subtract and compare to zero.  In this case,
	    // it doesn't really matter much, but it's simply a force of habit.

	    for( int i = (size - 1); i >= 0; i-- ) {
		IORInterceptor interceptor = iorInterceptors[i];
		try {
		    interceptor.establish_components( info );
	        }
		catch( Exception e ) {
		    // as per PI spec (orbos/99-12-02 sec 7.2.1), if
		    // establish_components throws an exception, ignore it.
		}
	    }

	    // Change the state so that only template operations are valid
	    info.makeStateEstablished() ;

	    for( int i = (size - 1); i >= 0; i-- ) {
		IORInterceptor interceptor = iorInterceptors[i];
		if (interceptor instanceof IORInterceptor_3_0) {
		    IORInterceptor_3_0 interceptor30 = (IORInterceptor_3_0)interceptor ;
		    // Note that exceptions here are NOT ignored, as per the
		    // ORT spec (orbos/01-01-04)
		    interceptor30.components_established( info );
		}
	    }

	    // Change the state so that no operations are valid,
	    // in case a reference to info escapes this scope.
	    // This also completes the actions associated with the
	    // template interceptors on this POA.
	    info.makeStateDone() ;
	}
    
voidsetEnabled(boolean enabled)
Enables or disables the interceptor invoker

	this.enabled = enabled;
    
private voidupdateClientRequestDispatcherForward(ClientRequestInfoImpl info)
Update the client delegate in the event of a ForwardRequest, given the information in the passed-in info object.

        ForwardRequest forwardRequest = info.getForwardRequestException();
        
        // ForwardRequest may be null if the forwarded IOR is set internal
        // to the ClientRequestDispatcher rather than explicitly through Portable
        // Interceptors.  In this case, we need not update the client 
        // delegate ForwardRequest object.
        if( forwardRequest != null ) {
            org.omg.CORBA.Object object = forwardRequest.forward;

            // Convert the forward object into an IOR:
	    IOR ior = ORBUtility.getIOR( object ) ;
	    info.setLocatedIOR( ior );
        }