FileDocCategorySizeDatePackage
CorbaMessageMediatorImpl.javaAPI DocJava SE 5 API73294Fri Aug 26 14:54:30 BST 2005com.sun.corba.se.impl.protocol

CorbaMessageMediatorImpl

public class CorbaMessageMediatorImpl extends Object implements CorbaMessageMediator, MessageHandler, CorbaProtocolHandler
author
Harold Carr

Fields Summary
protected ORB
orb
protected ORBUtilSystemException
wrapper
protected InterceptorsSystemException
interceptorWrapper
protected CorbaContactInfo
contactInfo
protected CorbaConnection
connection
protected short
addrDisposition
protected CDROutputObject
outputObject
protected CDRInputObject
inputObject
protected Message
messageHeader
protected RequestMessage
requestHeader
protected LocateReplyOrReplyMessage
replyHeader
protected String
replyExceptionDetailMessage
protected IOR
replyIOR
protected Integer
requestIdInteger
protected Message
dispatchHeader
protected ByteBuffer
dispatchByteBuffer
protected byte
streamFormatVersion
protected boolean
streamFormatVersionSet
protected Request
diiRequest
protected boolean
cancelRequestAlreadySent
protected ProtocolHandler
protocolHandler
protected boolean
_executeReturnServantInResponseConstructor
protected boolean
_executeRemoveThreadInfoInResponseConstructor
protected boolean
_executePIInResponseConstructor
protected boolean
isThreadDone
Constructors Summary
public CorbaMessageMediatorImpl(ORB orb, ContactInfo contactInfo, Connection connection, GIOPVersion giopVersion, IOR ior, int requestId, short addrDisposition, String operationName, boolean isOneWay)


    //
    // Client-side constructor.
    //

      
				     
				     
				     
				     
				     
				     
				     
				     
    
	this( orb, connection ) ;
	    
	this.contactInfo = (CorbaContactInfo) contactInfo;
	this.addrDisposition = addrDisposition;

	streamFormatVersion =
	    getStreamFormatVersionForThisRequest(
	        ((CorbaContactInfo)this.contactInfo).getEffectiveTargetIOR(),
		giopVersion);
	streamFormatVersionSet = true;

	requestHeader = (RequestMessage) MessageBase.createRequest(
            this.orb,
	    giopVersion,
	    ORBUtility.getEncodingVersion(orb, ior),
	    requestId,
	    !isOneWay,
	    ((CorbaContactInfo)this.contactInfo).getEffectiveTargetIOR(),
	    this.addrDisposition,
	    operationName,
	    new ServiceContexts(orb),
	    null);
    
public CorbaMessageMediatorImpl(ORB orb, Connection connection)

	this.orb = orb;
	this.connection = (CorbaConnection)connection;
	this.wrapper = ORBUtilSystemException.get( orb,
	    CORBALogDomains.RPC_PROTOCOL ) ;
	this.interceptorWrapper = InterceptorsSystemException.get( orb,
	    CORBALogDomains.RPC_PROTOCOL ) ;
    
public CorbaMessageMediatorImpl(ORB orb, CorbaConnection connection, Message dispatchHeader, ByteBuffer byteBuffer)

	this( orb, connection ) ;
	this.dispatchHeader = dispatchHeader;
        this.dispatchByteBuffer = byteBuffer;
    
Methods Summary
private voidaddExceptionDetailMessage(com.sun.corba.se.spi.protocol.CorbaMessageMediator mediator, org.omg.CORBA.SystemException ex, com.sun.corba.se.spi.servicecontext.ServiceContexts serviceContexts)

	ByteArrayOutputStream baos = new ByteArrayOutputStream();
	PrintWriter pw = new PrintWriter(baos);
	ex.printStackTrace(pw);
	pw.flush(); // NOTE: you must flush or baos will be empty.
	EncapsOutputStream encapsOutputStream = 
	    new EncapsOutputStream((ORB)mediator.getBroker());
	encapsOutputStream.putEndian();
	encapsOutputStream.write_wstring(baos.toString());
	UnknownServiceContext serviceContext =
	    new UnknownServiceContext(ExceptionDetailMessage.value,
				      encapsOutputStream.toByteArray());
	serviceContexts.put(serviceContext);
    
private voidbeginRequest(com.sun.corba.se.spi.protocol.CorbaMessageMediator messageMediator)

	ORB orb = (ORB) messageMediator.getBroker();
	if (orb.subcontractDebugFlag) {
	    dprint(".handleRequest->:");
	}
	connection.serverRequestProcessingBegins();
    
protected org.omg.CORBA.SystemExceptionconvertThrowableToSystemException(java.lang.Throwable throwable, org.omg.CORBA.CompletionStatus completionStatus)

	if (throwable instanceof SystemException) {
	    return (SystemException)throwable;
	}

	if (throwable instanceof RequestCanceledException) {
	    // Reporting an exception response causes the
	    // poa current stack, the interceptor stacks, etc.
	    // to be balanced.  It also notifies interceptors
	    // that the request was cancelled.

	    return wrapper.requestCanceled( throwable ) ;
	}

	// NOTE: We do not trap ThreadDeath above Throwable.
	// There is no reason to stop the thread.  It is
	// just a worker thread.  The ORB never throws
	// ThreadDeath.  Client code may (e.g., in ServantManagers,
	// interceptors, or servants) but that should not
	// effect the ORB threads.  So it is just handled
	// generically.

	//
	// Last resort.
	// If user code throws a non-SystemException report it generically.
	//

	return wrapper.runtimeexception( CompletionStatus.COMPLETED_MAYBE, throwable ) ;
    
private com.sun.corba.se.impl.encoding.CDROutputObjectcreateAppropriateOutputObject(com.sun.corba.se.spi.protocol.CorbaMessageMediator messageMediator, com.sun.corba.se.impl.protocol.giopmsgheaders.Message msg, com.sun.corba.se.impl.protocol.giopmsgheaders.LocateReplyMessage reply)

	CDROutputObject outputObject;

	if (msg.getGIOPVersion().lessThan(GIOPVersion.V1_2)) {
	    // locate msgs 1.0 & 1.1 :=> grow, 
	    // REVISIT - build from factory
	    outputObject = new CDROutputObject(
		             (ORB) messageMediator.getBroker(),
			     this,
			     GIOPVersion.V1_0,
			     (CorbaConnection) messageMediator.getConnection(),
			     reply,
			     ORBConstants.STREAM_FORMAT_VERSION_1);
	} else {
	    // 1.2 :=> stream
	    // REVISIT - build from factory
	    outputObject = new CDROutputObject(
		             (ORB) messageMediator.getBroker(),
			     messageMediator,
			     reply,
			     ORBConstants.STREAM_FORMAT_VERSION_1);
	}
	return outputObject;
    
public org.omg.CORBA.portable.OutputStreamcreateExceptionReply()

	// Note: relies on side-effect of setting mediator output field.
	// REVISIT - cast - need interface
	getProtocolHandler().createUserExceptionResponse(this, (ServiceContexts) null);
	return (OutputStream) getOutputObject();
    
public com.sun.corba.se.spi.protocol.CorbaMessageMediatorcreateLocationForward(com.sun.corba.se.spi.protocol.CorbaMessageMediator messageMediator, com.sun.corba.se.spi.ior.IOR ior, com.sun.corba.se.spi.servicecontext.ServiceContexts svc)

        ReplyMessage reply 
            = MessageBase.createReply(
                  (ORB)messageMediator.getBroker(),
		  messageMediator.getGIOPVersion(),
		  messageMediator.getEncodingVersion(),
		  messageMediator.getRequestId(), 
		  ReplyMessage.LOCATION_FORWARD,
		  getServiceContextsForReply(messageMediator, svc), 
		  ior);

	return createResponseHelper(messageMediator, reply, ior);
    
public org.omg.CORBA.portable.OutputStreamcreateReply()

	// Note: relies on side-effect of setting mediator output field.
	// REVISIT - cast - need interface
	getProtocolHandler().createResponse(this, (ServiceContexts) null);
	return (OutputStream) getOutputObject();
    
public com.sun.corba.se.spi.protocol.CorbaMessageMediatorcreateResponse(com.sun.corba.se.spi.protocol.CorbaMessageMediator messageMediator, com.sun.corba.se.spi.servicecontext.ServiceContexts svc)

	// REVISIT: ignore service contexts during framework transition.
	// They are set in SubcontractResponseHandler to the wrong connection.
	// Then they would be set again here and a duplicate contexts
	// exception occurs.
	return createResponseHelper(
            messageMediator,
	    getServiceContextsForReply(messageMediator, null));
    
protected com.sun.corba.se.spi.protocol.CorbaMessageMediatorcreateResponseHelper(com.sun.corba.se.spi.protocol.CorbaMessageMediator messageMediator, com.sun.corba.se.spi.servicecontext.ServiceContexts svc)

	ReplyMessage message = 
	    MessageBase.createReply(
		(ORB)messageMediator.getBroker(),
		messageMediator.getGIOPVersion(),
		messageMediator.getEncodingVersion(),
		messageMediator.getRequestId(),
		ReplyMessage.NO_EXCEPTION,
		svc,
		null);
	return createResponseHelper(messageMediator, message, null);
    
protected com.sun.corba.se.spi.protocol.CorbaMessageMediatorcreateResponseHelper(com.sun.corba.se.spi.protocol.CorbaMessageMediator messageMediator, com.sun.corba.se.spi.servicecontext.ServiceContexts svc, boolean user)

	ReplyMessage message =
            MessageBase.createReply(
                (ORB)messageMediator.getBroker(),
		messageMediator.getGIOPVersion(), 
		messageMediator.getEncodingVersion(),
		messageMediator.getRequestId(),
		user ? ReplyMessage.USER_EXCEPTION :
		       ReplyMessage.SYSTEM_EXCEPTION,
		svc,
		null);
	return createResponseHelper(messageMediator, message, null);
    
protected com.sun.corba.se.spi.protocol.CorbaMessageMediatorcreateResponseHelper(com.sun.corba.se.spi.protocol.CorbaMessageMediator messageMediator, com.sun.corba.se.impl.protocol.giopmsgheaders.ReplyMessage reply, com.sun.corba.se.spi.ior.IOR ior)

	// REVISIT - these should be invoked from subcontract.
	runServantPostInvoke(messageMediator);
	runInterceptors(messageMediator, reply);
	runRemoveThreadInfo(messageMediator);

        if (((ORB)messageMediator.getBroker()).subcontractDebugFlag) {
	    dprint(".createResponseHelper: " 
		   + opAndId(messageMediator) + ": "
		   + reply);
	}
		      
	messageMediator.setReplyHeader(reply);

	OutputObject replyOutputObject;
	// REVISIT = do not use null.
	// 
	if (messageMediator.getConnection() == null) {
	    // REVISIT - needs factory
	    replyOutputObject = 
		new CDROutputObject(orb, messageMediator,
				    messageMediator.getReplyHeader(),
				    messageMediator.getStreamFormatVersion(),
				    BufferManagerFactory.GROW);
	} else {
	    replyOutputObject = messageMediator.getConnection().getAcceptor()
	     .createOutputObject(messageMediator.getBroker(), messageMediator);
	}
	messageMediator.setOutputObject(replyOutputObject);
	messageMediator.getOutputObject().setMessageMediator(messageMediator);

	reply.write((OutputStream) messageMediator.getOutputObject());
	if (reply.getIOR() != null) {
	    reply.getIOR().write((OutputStream) messageMediator.getOutputObject());
	}
	// REVISIT - not necessary?
	//messageMediator.this.replyIOR = reply.getIOR();

	// NOTE: The mediator holds onto output object so return value
	// not really necessary.
	return messageMediator;
    
public com.sun.corba.se.spi.protocol.CorbaMessageMediatorcreateSystemExceptionResponse(com.sun.corba.se.spi.protocol.CorbaMessageMediator messageMediator, org.omg.CORBA.SystemException ex, com.sun.corba.se.spi.servicecontext.ServiceContexts svc)

	if (messageMediator.getConnection() != null) {
	    // It is possible that fragments of response have already been
	    // sent.  Then an error may occur (e.g. marshaling error like
	    // non serializable object).  In that case it is too late
	    // to send the exception.  We just return the existing fragmented
	    // stream here.  This will cause an incomplete last fragment
	    // to be sent.  Then the other side will get a marshaling error
	    // when attempting to unmarshal.
	    
	    // REVISIT: Impl - make interface method to do the following.
	    CorbaMessageMediatorImpl mediator = (CorbaMessageMediatorImpl)
		((CorbaConnection)messageMediator.getConnection())
		.serverRequestMapGet(messageMediator.getRequestId());

	    OutputObject existingOutputObject = null;
	    if (mediator != null) {
		existingOutputObject = mediator.getOutputObject();
	    }

	    // REVISIT: need to think about messageMediator containing correct
	    // pointer to output object.
	    if (existingOutputObject != null &&
		mediator.sentFragment() && 
		! mediator.sentFullMessage())
	    {
		return mediator;
	    }
	}
    
	// Only do this if interceptors have been initialized on this request
	// and have not completed their lifecycle (otherwise the info stack
	// may be empty or have a different request's entry on top).
	if (messageMediator.executePIInResponseConstructor()) {
	    // REVISIT: not necessary in framework now?
	    // Inform Portable Interceptors of the SystemException.  This is
	    // required to be done here because the ending interception point
	    // is called in the when creating the response below
	    // but we do not currently write the SystemException into the 
	    // response until after the ending point is called.
	    ((ORB)messageMediator.getBroker()).getPIHandler().setServerPIInfo( ex );
	}

	if (((ORB)messageMediator.getBroker()).subcontractDebugFlag &&
	    ex != null)
        {
            dprint(".createSystemExceptionResponse: " 
		   + opAndId(messageMediator),
		   ex);
	}

	ServiceContexts serviceContexts = 
	    getServiceContextsForReply(messageMediator, svc);

	// NOTE: We MUST add the service context before creating
	// the response since service contexts are written to the
	// stream when the response object is created.

	addExceptionDetailMessage(messageMediator, ex, serviceContexts);

        CorbaMessageMediator response =
	    createResponseHelper(messageMediator, serviceContexts, false);

	// NOTE: From here on, it is too late to add more service contexts.
	// They have already been serialized to the stream (and maybe fragments
	// sent).

	ORBUtility.writeSystemException(
            ex, (OutputStream)response.getOutputObject());

	return response;
    
public com.sun.corba.se.spi.protocol.CorbaMessageMediatorcreateUnknownExceptionResponse(com.sun.corba.se.spi.protocol.CorbaMessageMediator messageMediator, org.omg.CORBA.portable.UnknownException ex)

	// NOTE: This service context container gets augmented in
	// tail call.
	ServiceContexts contexts = null;
	SystemException sys = new UNKNOWN( 0, 
	    CompletionStatus.COMPLETED_MAYBE);
	contexts = new ServiceContexts( (ORB)messageMediator.getBroker() );
	UEInfoServiceContext uei = new UEInfoServiceContext(sys);
	contexts.put( uei ) ;
	return createSystemExceptionResponse(messageMediator, sys, contexts);
    
public com.sun.corba.se.spi.protocol.CorbaMessageMediatorcreateUserExceptionResponse(com.sun.corba.se.spi.protocol.CorbaMessageMediator messageMediator, com.sun.corba.se.spi.servicecontext.ServiceContexts svc)

	// REVISIT - same as above
	return createResponseHelper(
            messageMediator,
	    getServiceContextsForReply(messageMediator, null),
	    true);
    
private voiddispatchError(com.sun.corba.se.spi.protocol.CorbaMessageMediator messageMediator, java.lang.String msg, java.lang.Throwable t)

	if (orb.subcontractDebugFlag) {
	    dprint(".handleRequest: " + opAndId(messageMediator) 
		   + ": !!ERROR!!: "
		   + msg,
		   t);
	}
	// REVISIT - this makes hcks sendTwoObjects fail
	// messageMediator.getConnection().close();
    
private voiddprint(java.lang.String msg, java.lang.Throwable t)

	dprint(msg);
	t.printStackTrace(System.out);
    
private voiddprint(java.lang.String msg)

	ORBUtility.dprint("CorbaMessageMediatorImpl", msg);
    
private voidendRequest(com.sun.corba.se.spi.protocol.CorbaMessageMediator messageMediator)

	ORB orb = (ORB) messageMediator.getBroker();
	if (orb.subcontractDebugFlag) {
	    dprint(".handleRequest<-: " + opAndId(messageMediator));
	}

        // release NIO ByteBuffers to ByteBufferPool

        try {
            OutputObject outputObj = messageMediator.getOutputObject();
            if (outputObj != null) {
		outputObj.close();
            }
            InputObject inputObj = messageMediator.getInputObject();
            if (inputObj != null) {
		inputObj.close();
            }
        } catch (IOException ex) {
            // Given what close() does, this catch shouldn't ever happen.
            // See CDRInput/OutputObject.close() for more info.
            // It also won't result in a Corba error if an IOException happens.
	    if (orb.subcontractDebugFlag) {
                dprint(".endRequest: IOException:" + ex.getMessage(), ex);
	    }
        } finally {
	    ((CorbaConnection)messageMediator.getConnection()).serverRequestProcessingEnds();
	}
    
public booleanexecutePIInResponseConstructor()

	return _executePIInResponseConstructor;
    
public booleanexecuteRemoveThreadInfoInResponseConstructor()

	return _executeRemoveThreadInfoInResponseConstructor;
    
public booleanexecuteReturnServantInResponseConstructor()

	return _executeReturnServantInResponseConstructor;

    
public voidfinishSendingRequest()

	// REVISIT: probably move logic in outputObject to here.
        outputObject.finishSendingMessage();
    
public shortgetAddrDisposition()

	return addrDisposition;
    
public shortgetAddrDispositionReply()

	return replyHeader.getAddrDisposition();
    
public com.sun.corba.se.pept.broker.BrokergetBroker()

	return orb;
    
public com.sun.corba.se.pept.transport.ConnectiongetConnection()

	return connection;
    
public com.sun.corba.se.pept.transport.ContactInfogetContactInfo()

	return contactInfo;
    
public java.nio.ByteBuffergetDispatchBuffer()

	return dispatchByteBuffer;
    
public com.sun.corba.se.impl.protocol.giopmsgheaders.MessagegetDispatchHeader()

	return dispatchHeader;
    
public bytegetEncodingVersion()

	if (messageHeader != null) {
	    return messageHeader.getEncodingVersion();
	}
	return getRequestHeader().getEncodingVersion();
    
public com.sun.corba.se.spi.ior.IORgetForwardedIOR()

	return replyHeader.getIOR();
    
public com.sun.corba.se.spi.ior.iiop.GIOPVersiongetGIOPVersion()

	if (messageHeader != null) {
	    return messageHeader.getGIOPVersion();
	}
	return getRequestHeader().getGIOPVersion();
    
public com.sun.corba.se.pept.encoding.InputObjectgetInputObject()

	return inputObject;
    
public com.sun.corba.se.impl.protocol.giopmsgheaders.LocateReplyMessagegetLocateReplyHeader()

	return (LocateReplyMessage) replyHeader;
    
public com.sun.corba.se.spi.ior.ObjectKeygetObjectKey()

	return getRequestHeader().getObjectKey();
    
public java.lang.StringgetOperationName()

	return getRequestHeader().getOperation();
    
public com.sun.corba.se.pept.encoding.OutputObjectgetOutputObject()

	return outputObject;
    
public com.sun.corba.se.spi.protocol.CorbaProtocolHandlergetProtocolHandler()

	// REVISIT: should look up in orb registry.
	return this;
    
public com.sun.corba.se.impl.protocol.giopmsgheaders.ReplyMessagegetReplyHeader()

	return (ReplyMessage) replyHeader;
    
public com.sun.corba.se.spi.servicecontext.ServiceContextsgetReplyServiceContexts()

	return getReplyHeader().getServiceContexts();
    
public com.sun.corba.se.impl.protocol.giopmsgheaders.RequestMessagegetRequestHeader()

	return requestHeader;
    
public intgetRequestId()

	return getRequestHeader().getRequestId();
    
public java.lang.IntegergetRequestIdInteger()

	if (requestIdInteger == null) {
	    requestIdInteger = new Integer(getRequestHeader().getRequestId());
	}
	return requestIdInteger;
    
public com.sun.corba.se.spi.servicecontext.ServiceContextsgetRequestServiceContexts()

	return getRequestHeader().getServiceContexts();
    
protected com.sun.corba.se.spi.servicecontext.ServiceContextsgetServiceContextsForReply(com.sun.corba.se.spi.protocol.CorbaMessageMediator messageMediator, com.sun.corba.se.spi.servicecontext.ServiceContexts contexts)

	CorbaConnection c = (CorbaConnection) messageMediator.getConnection();

        if (((ORB)messageMediator.getBroker()).subcontractDebugFlag) {
            dprint(".getServiceContextsForReply: " 
		   + opAndId(messageMediator)
		   + ": " + c);
	}

        if (contexts == null) {
            contexts = new ServiceContexts(((ORB)messageMediator.getBroker()));
	}
			
	// NOTE : We only want to send the runtime context the first time

	if (c != null && !c.isPostInitialContexts()) {
	    c.setPostInitialContexts();
	    SendingContextServiceContext scsc = 
		new SendingContextServiceContext( 
		    ((ORB)messageMediator.getBroker()).getFVDCodeBaseIOR()) ; 

	    if (contexts.get( scsc.getId() ) != null)
		throw wrapper.duplicateSendingContextServiceContext() ;

	    contexts.put( scsc ) ;

	    if ( ((ORB)messageMediator.getBroker()).subcontractDebugFlag) 
                dprint(".getServiceContextsForReply: "
		       + opAndId(messageMediator)
		       + ": added SendingContextServiceContext" ) ;
	}

        // send ORBVersion servicecontext as part of the Reply

        ORBVersionServiceContext ovsc 
            = new ORBVersionServiceContext(ORBVersionFactory.getORBVersion());

	if (contexts.get( ovsc.getId() ) != null)
	    throw wrapper.duplicateOrbVersionServiceContext() ;

	contexts.put( ovsc ) ;

	if ( ((ORB)messageMediator.getBroker()).subcontractDebugFlag)
	    dprint(".getServiceContextsForReply: "
		   + opAndId(messageMediator)
	           + ": added ORB version service context");

        return contexts;
    
public bytegetStreamFormatVersion()

	// REVISIT: ContactInfo/Acceptor output object factories
	// just use this.  Maybe need to distinguish:
	//    createOutputObjectForRequest
	//    createOutputObjectForReply
	// then do getStreamFormatVersionForRequest/ForReply here.
	if (streamFormatVersionSet) {
	    return streamFormatVersion;
	}
	return getStreamFormatVersionForReply();
    
public bytegetStreamFormatVersionForReply()
If the RMI-IIOP maximum stream format version service context is present, it indicates the maximum stream format version we could use for the reply. If it isn't present, the default is 2 for GIOP 1.3 or greater, 1 for lower. This is only sent on requests. Clients can find out the server's maximum by looking for a tagged component in the IOR.


	// NOTE: The request service contexts may indicate the max.
        ServiceContexts svc = getRequestServiceContexts();

	MaxStreamFormatVersionServiceContext msfvsc
	    = (MaxStreamFormatVersionServiceContext)svc.get(
		MaxStreamFormatVersionServiceContext.SERVICE_CONTEXT_ID);
	    
	if (msfvsc != null) {
            byte localMaxVersion = ORBUtility.getMaxStreamFormatVersion();
            byte remoteMaxVersion = msfvsc.getMaximumStreamFormatVersion();

            return (byte)Math.min(localMaxVersion, remoteMaxVersion);
        } else {
            // Defaults to 1 for GIOP 1.2 or less, 2 for
            // GIOP 1.3 or higher.
            if (getGIOPVersion().lessThan(GIOPVersion.V1_3))
                return ORBConstants.STREAM_FORMAT_VERSION_1;
            else
                return ORBConstants.STREAM_FORMAT_VERSION_2;
        }
    
private bytegetStreamFormatVersionForThisRequest(com.sun.corba.se.spi.ior.IOR ior, com.sun.corba.se.spi.ior.iiop.GIOPVersion giopVersion)


        byte localMaxVersion
            = ORBUtility.getMaxStreamFormatVersion();

	IOR effectiveTargetIOR = 
	    ((CorbaContactInfo)this.contactInfo).getEffectiveTargetIOR();
        IIOPProfileTemplate temp =
	    (IIOPProfileTemplate)effectiveTargetIOR.getProfile().getTaggedProfileTemplate();
        Iterator iter = temp.iteratorById(TAG_RMI_CUSTOM_MAX_STREAM_FORMAT.value);
        if (!iter.hasNext()) {
            // Didn't have the max stream format version tagged
            // component.
            if (giopVersion.lessThan(GIOPVersion.V1_3))
                return ORBConstants.STREAM_FORMAT_VERSION_1;
            else
                return ORBConstants.STREAM_FORMAT_VERSION_2;
        }

        byte remoteMaxVersion
            = ((MaxStreamFormatVersionComponent)iter.next()).getMaxStreamFormatVersion();

        return (byte)Math.min(localMaxVersion, remoteMaxVersion);
    
public org.omg.CORBA.SystemExceptiongetSystemExceptionReply()

	return replyHeader.getSystemException(replyExceptionDetailMessage);
    
public intgetThreadPoolToUse()

	int poolToUse = 0;
	Message msg = getDispatchHeader();
	// A null msg should never happen. But, we'll be
	// defensive just in case.
	if (msg != null) {
	    poolToUse = msg.getThreadPoolToUse();
	}
	return poolToUse;
    
protected voidhandleAddressingDisposition(com.sun.corba.se.spi.protocol.CorbaMessageMediator messageMediator, com.sun.corba.se.impl.protocol.AddressingDispositionException ex)


	short addrDisp = -1;

	// from iiop.RequestProcessor.

	// Respond with expected target addressing disposition.
                    
	switch (messageMediator.getRequestHeader().getType()) {
	case Message.GIOPRequest :
	    ReplyMessage replyHeader = MessageBase.createReply(
		          (ORB)messageMediator.getBroker(),
			  messageMediator.getGIOPVersion(),
			  messageMediator.getEncodingVersion(),
			  messageMediator.getRequestId(),
			  ReplyMessage.NEEDS_ADDRESSING_MODE, 
			  null, null);
	    // REVISIT: via acceptor factory.
	    CDROutputObject outputObject = new CDROutputObject(
                (ORB)messageMediator.getBroker(),
		this,
		messageMediator.getGIOPVersion(),
		(CorbaConnection)messageMediator.getConnection(),
		replyHeader,
		ORBConstants.STREAM_FORMAT_VERSION_1);
	    messageMediator.setOutputObject(outputObject);
	    outputObject.setMessageMediator(messageMediator);
	    replyHeader.write(outputObject);
	    AddressingDispositionHelper.write(outputObject,
					      ex.expectedAddrDisp());
	    return;

	case Message.GIOPLocateRequest :
	    LocateReplyMessage locateReplyHeader = MessageBase.createLocateReply(
	        (ORB)messageMediator.getBroker(),
		messageMediator.getGIOPVersion(),
		messageMediator.getEncodingVersion(),
		messageMediator.getRequestId(),
		LocateReplyMessage.LOC_NEEDS_ADDRESSING_MODE,
		null);                                   

	    addrDisp = ex.expectedAddrDisp();

	    // REVISIT: via acceptor factory.
	    outputObject = 
		createAppropriateOutputObject(messageMediator,
					      messageMediator.getRequestHeader(),
					      locateReplyHeader);
	    messageMediator.setOutputObject(outputObject);
	    outputObject.setMessageMediator(messageMediator);
	    locateReplyHeader.write(outputObject);
	    IOR ior = null;
	    if (ior != null) {
		ior.write(outputObject);
	    }
	    if (addrDisp != -1) {
		AddressingDispositionHelper.write(outputObject, addrDisp);
	    }
	    return;
	}
    
public voidhandleDIIReply(org.omg.CORBA_2_3.portable.InputStream inputStream)

	if (! isDIIRequest()) {
	    return;
	}
	((RequestImpl)diiRequest).unmarshalReply(inputStream);
    
public voidhandleInput(com.sun.corba.se.impl.protocol.giopmsgheaders.Message header)

	try {
	    messageHeader = header;

	    if (transportDebug())
		dprint(".handleInput->: " 
		       + MessageBase.typeToString(header.getType()));

	    setWorkThenReadOrResumeSelect(header);

	    switch(header.getType()) 
            {
            case Message.GIOPCloseConnection:
		if (transportDebug()) {
		    dprint(".handleInput: CloseConnection: purging");
		}
                connection.purgeCalls(wrapper.connectionRebind(), true, false);
                break;
            case Message.GIOPMessageError:
		if (transportDebug()) {
		    dprint(".handleInput: MessageError: purging");
		}
                connection.purgeCalls(wrapper.recvMsgError(), true, false);
                break;
            default:
		if (transportDebug()) {
		    dprint(".handleInput: ERROR: "
			   + MessageBase.typeToString(header.getType()));
		}
		throw wrapper.badGiopRequestType() ;
	    }
            releaseByteBufferToPool();
	} finally {
	    if (transportDebug()) {
		dprint(".handleInput<-: " 
		       + MessageBase.typeToString(header.getType()));
	    }
	}
    
public voidhandleInput(com.sun.corba.se.impl.protocol.giopmsgheaders.RequestMessage_1_0 header)

	try {
	    if (transportDebug()) dprint(".REQUEST 1.0->: " + header);
	    try {
		messageHeader = requestHeader = (RequestMessage) header;
		setInputObject();
	    } finally {
		setWorkThenPoolOrResumeSelect(header);
	    }
	    getProtocolHandler().handleRequest(header, this);
	} catch (Throwable t) {
	    if (transportDebug())
		dprint(".REQUEST 1.0: !!ERROR!!: " + header, t);
	    // Mask the exception from thread.;
	} finally {
	    if (transportDebug()) dprint(".REQUEST 1.0<-: " + header);
	}
    
public voidhandleInput(com.sun.corba.se.impl.protocol.giopmsgheaders.RequestMessage_1_1 header)

	try {
	    if (transportDebug()) dprint(".REQUEST 1.1->: " + header);
	    try {
		messageHeader = requestHeader = (RequestMessage) header;
		setInputObject();
		connection.serverRequest_1_1_Put(this);
	    } finally {
		setWorkThenPoolOrResumeSelect(header);
	    }
	    getProtocolHandler().handleRequest(header, this);
	} catch (Throwable t) {
	    if (transportDebug())
		dprint(".REQUEST 1.1: !!ERROR!!: " + header, t);
	    // Mask the exception from thread.;
	} finally {
	    if (transportDebug()) dprint(".REQUEST 1.1<-: " + header);
	}
    
public voidhandleInput(com.sun.corba.se.impl.protocol.giopmsgheaders.RequestMessage_1_2 header)

	try {
	    try {

		messageHeader = requestHeader = (RequestMessage) header;

		header.unmarshalRequestID(dispatchByteBuffer);
		setInputObject();

		if (transportDebug()) dprint(".REQUEST 1.2->: id/" 
					     + header.getRequestId() 
					     + ": "
					     + header);
	    
		// NOTE: in the old code this used to be done conditionally:
		// if (header.moreFragmentsToFollow()).
		// Now we always put it in. We take it out when
		// the response is done.
		// This must happen now so if a header is fragmented the stream
		// may be found.
		connection.serverRequestMapPut(header.getRequestId(), this);
	    } finally {
		// Leader/Follower.
		// Note: This *MUST* come after putting stream in above map
		// since the header may be fragmented and you do not want to
		// start reading again until the map above is set.
		setWorkThenPoolOrResumeSelect(header);
	    }
	    //inputObject.unmarshalHeader(); // done in subcontract.
	    getProtocolHandler().handleRequest(header, this);
	} catch (Throwable t) {
	    if (transportDebug()) dprint(".REQUEST 1.2: id/"
					 + header.getRequestId()
					 + ": !!ERROR!!: "
					 + header,
					 t);
	    // Mask the exception from thread.;
	} finally {
	    connection.serverRequestMapRemove(header.getRequestId());

	    if (transportDebug()) dprint(".REQUEST 1.2<-: id/" 
					 + header.getRequestId() 
					 + ": "
					 + header);
	}
    
public voidhandleInput(com.sun.corba.se.impl.protocol.giopmsgheaders.ReplyMessage_1_0 header)

	try {
	    try {
		if (transportDebug()) dprint(".REPLY 1.0->: " + header);
		messageHeader = replyHeader = (ReplyMessage) header;
		setInputObject();

		// REVISIT: this should be done by waiting thread.
		inputObject.unmarshalHeader();

		signalResponseReceived();
	    } finally{
		setWorkThenReadOrResumeSelect(header);
	    }
	} catch (Throwable t) {
	    if (transportDebug())dprint(".REPLY 1.0: !!ERROR!!: " + header, t);
	    // Mask the exception from thread.;
	} finally {
	    if (transportDebug()) dprint(".REPLY 1.0<-: " + header);
	}
    
public voidhandleInput(com.sun.corba.se.impl.protocol.giopmsgheaders.ReplyMessage_1_1 header)

	try {
	    if (transportDebug()) dprint(".REPLY 1.1->: " + header);
	    messageHeader = replyHeader = (ReplyMessage) header;
	    setInputObject();

	    if (header.moreFragmentsToFollow()) {

		// More fragments are coming to complete this reply, so keep
		// a reference to the InputStream so we can add the fragments
		connection.clientReply_1_1_Put(this);
            
		// In 1.1, we can't assume that we have the request ID in the
		// first fragment.  Thus, another thread is used 
		// to be the reader while this thread unmarshals
		// the extended header and wakes up the client thread.
		setWorkThenPoolOrResumeSelect(header);

		// REVISIT - error handling.
		// This must be done now.
		inputObject.unmarshalHeader();

		signalResponseReceived();

	    } else {

		// Not fragmented, therefore we know the request
		// ID is here.  Thus, we can unmarshal the extended header
		// and wake up the client thread without using a third
		// thread as above.

		// REVISIT - error handling during unmarshal.
		// This must be done now to get the request id.
		inputObject.unmarshalHeader();

		signalResponseReceived();

		setWorkThenReadOrResumeSelect(header);
	    }
	} catch (Throwable t) {
	    if (transportDebug()) dprint(".REPLY 1.1: !!ERROR!!: " + header);
	    // Mask the exception from thread.;
	} finally {
	    if (transportDebug()) dprint(".REPLY 1.1<-: " + header);
	}
    
public voidhandleInput(com.sun.corba.se.impl.protocol.giopmsgheaders.ReplyMessage_1_2 header)

	try {
	    try {
		messageHeader = replyHeader = (ReplyMessage) header;

		// We know that the request ID is in the first fragment
		header.unmarshalRequestID(dispatchByteBuffer);

		if (transportDebug()) {
		    dprint(".REPLY 1.2->: id/" 
			   + + header.getRequestId()
			   + ": more?: " + header.moreFragmentsToFollow()
			   + ": " + header);
		}
		
		setInputObject();

		signalResponseReceived();
	    } finally {
		setWorkThenReadOrResumeSelect(header);
	    }
	} catch (Throwable t) {
	    if (transportDebug()) dprint(".REPLY 1.2: id/"
					 + header.getRequestId()
					 + ": !!ERROR!!: " 
					 + header, t);
	    // Mask the exception from thread.;
	} finally {
	    if (transportDebug()) dprint(".REPLY 1.2<-: id/"
					 + header.getRequestId() 
					 + ": "
					 + header);
	}
    
public voidhandleInput(com.sun.corba.se.impl.protocol.giopmsgheaders.LocateRequestMessage_1_0 header)

	try {
	    if (transportDebug())
		dprint(".LOCATE_REQUEST 1.0->: " + header);
	    try {
		messageHeader = header;
		setInputObject();
	    } finally {
		setWorkThenPoolOrResumeSelect(header);
	    }
	    getProtocolHandler().handleRequest(header, this);
	} catch (Throwable t) {
	    if (transportDebug()) 
		dprint(".LOCATE_REQUEST 1.0: !!ERROR!!: " + header, t);
	    // Mask the exception from thread.;
	} finally {
	    if (transportDebug()) 
		dprint(".LOCATE_REQUEST 1.0<-: " + header);
	}

    
public voidhandleInput(com.sun.corba.se.impl.protocol.giopmsgheaders.LocateRequestMessage_1_1 header)

	try {
	    if (transportDebug()) 
		dprint(".LOCATE_REQUEST 1.1->: " + header);
	    try {
		messageHeader = header;
		setInputObject();
	    } finally {
		setWorkThenPoolOrResumeSelect(header);
	    }
	    getProtocolHandler().handleRequest(header, this);
	} catch (Throwable t) {
	    if (transportDebug()) 
		dprint(".LOCATE_REQUEST 1.1: !!ERROR!!: " + header, t);
	    // Mask the exception from thread.;
	} finally {
	    if (transportDebug()) 
		dprint(".LOCATE_REQUEST 1.1<-:" + header);
	}
    
public voidhandleInput(com.sun.corba.se.impl.protocol.giopmsgheaders.LocateRequestMessage_1_2 header)

	try {
	    try {
		messageHeader = header;

		header.unmarshalRequestID(dispatchByteBuffer);
		setInputObject();

		if (transportDebug()) 
		    dprint(".LOCATE_REQUEST 1.2->: id/"
			   + header.getRequestId() 
			   + ": "
			   + header);

		if (header.moreFragmentsToFollow()) {
		    connection.serverRequestMapPut(header.getRequestId(),this);
		}
	    } finally {
		setWorkThenPoolOrResumeSelect(header);
	    }
	    getProtocolHandler().handleRequest(header, this);
	} catch (Throwable t) {
	    if (transportDebug()) 
		dprint(".LOCATE_REQUEST 1.2: id/"
		       + header.getRequestId()
		       + ": !!ERROR!!: " 
		       + header, t);
	    // Mask the exception from thread.;
	} finally {
	    if (transportDebug()) 
		dprint(".LOCATE_REQUEST 1.2<-: id/"
		       + header.getRequestId() 
		       + ": "
		       + header);
	}
    
public voidhandleInput(com.sun.corba.se.impl.protocol.giopmsgheaders.LocateReplyMessage_1_0 header)

	try {
	    if (transportDebug()) 
		dprint(".LOCATE_REPLY 1.0->:" + header);
	    try {
		messageHeader = header;
		setInputObject();
		inputObject.unmarshalHeader(); // REVISIT Put in subcontract.
		signalResponseReceived();
	    } finally {
		setWorkThenReadOrResumeSelect(header);
	    }
	} catch (Throwable t) {
	    if (transportDebug()) 
		dprint(".LOCATE_REPLY 1.0: !!ERROR!!: " + header, t);
	    // Mask the exception from thread.;
	} finally {
	    if (transportDebug()) 
		dprint(".LOCATE_REPLY 1.0<-: " + header);
	}
    
public voidhandleInput(com.sun.corba.se.impl.protocol.giopmsgheaders.LocateReplyMessage_1_1 header)

	try {
	    if (transportDebug()) dprint(".LOCATE_REPLY 1.1->: " + header);
	    try {
		messageHeader = header;
		setInputObject();
		// Fragmented LocateReplies are not allowed in 1.1.
		inputObject.unmarshalHeader();
		signalResponseReceived();
	    } finally {
		setWorkThenReadOrResumeSelect(header);
	    }
	} catch (Throwable t) {
	    if (transportDebug()) 
		dprint(".LOCATE_REPLY 1.1: !!ERROR!!: " + header, t);
	    // Mask the exception from thread.;
	} finally {
	    if (transportDebug()) dprint(".LOCATE_REPLY 1.1<-: " + header);
	}
    
public voidhandleInput(com.sun.corba.se.impl.protocol.giopmsgheaders.LocateReplyMessage_1_2 header)

	try {
	    try {
		messageHeader = header;

		// No need to put in client reply map - already there.
		header.unmarshalRequestID(dispatchByteBuffer);

		setInputObject();

		if (transportDebug()) dprint(".LOCATE_REPLY 1.2->: id/"
					     + header.getRequestId() 
					     + ": "
					     + header);

		signalResponseReceived();
	    } finally {
		setWorkThenPoolOrResumeSelect(header); // REVISIT
	    }
	} catch (Throwable t) {
	    if (transportDebug()) 
		dprint(".LOCATE_REPLY 1.2: id/"
		       + header.getRequestId()
		       + ": !!ERROR!!: " 
		       + header, t);
	    // Mask the exception from thread.;
	} finally {
	    if (transportDebug()) dprint(".LOCATE_REPLY 1.2<-: id/"
					 + header.getRequestId() 
					 + ": "
					 + header);
	}
    
public voidhandleInput(com.sun.corba.se.impl.protocol.giopmsgheaders.FragmentMessage_1_1 header)

	try {
	    if (transportDebug()) {
		dprint(".FRAGMENT 1.1->: "
		       + "more?: " + header.moreFragmentsToFollow()
		       + ": " + header);
	    }
	    try {
		messageHeader = header;
		MessageMediator mediator = null;
		CDRInputObject inputObject = null;

		if (connection.isServer()) {
		    mediator = connection.serverRequest_1_1_Get();
		} else {
		    mediator = connection.clientReply_1_1_Get();
		}
		if (mediator != null) {
		    inputObject = (CDRInputObject) mediator.getInputObject();
		}

		// If no input stream available, then discard the fragment.
		// This can happen:
		// 1. if a fragment message is received prior to receiving
		//    the original request/reply message. Very unlikely.
		// 2. if a fragment message is received after the
		//    reply has been sent (early replies)
		// Note: In the case of early replies, the fragments received
		// during the request processing (which are never unmarshaled),
		// will eventually be discarded by the GC.
		if (inputObject == null) {
		    if (transportDebug()) 
			dprint(".FRAGMENT 1.1: ++++DISCARDING++++: " + header);
                    // need to release dispatchByteBuffer to pool if
                    // we are discarding
                    releaseByteBufferToPool();
		    return;
		}

		inputObject.getBufferManager()
		    .processFragment(dispatchByteBuffer, header);

		if (! header.moreFragmentsToFollow()) {
		    if (connection.isServer()) {
			connection.serverRequest_1_1_Remove();
		    } else {
			connection.clientReply_1_1_Remove();
		    }
		}
	    } finally {
		// NOTE: This *must* come after queing the fragment
		// when using the selector to ensure fragments stay in order.
		setWorkThenReadOrResumeSelect(header);
	    }
	} catch (Throwable t) {
	    if (transportDebug()) 
		dprint(".FRAGMENT 1.1: !!ERROR!!: " + header, t);
	    // Mask the exception from thread.;
	} finally {
	    if (transportDebug()) dprint(".FRAGMENT 1.1<-: " + header);
	}
    
public voidhandleInput(com.sun.corba.se.impl.protocol.giopmsgheaders.FragmentMessage_1_2 header)

	try {
	    try {
		messageHeader = header;

		// Note:  We know it's a 1.2 fragment, we have the data, but
		// we need the IIOPInputStream instance to unmarshal the
		// request ID... but we need the request ID to get the
		// IIOPInputStream instance. So we peek at the raw bytes.

		header.unmarshalRequestID(dispatchByteBuffer);

		if (transportDebug()) {
		    dprint(".FRAGMENT 1.2->: id/"
			   + header.getRequestId()
			   + ": more?: " + header.moreFragmentsToFollow()
			   + ": " + header);
		}

		MessageMediator mediator = null;
		InputObject inputObject = null;

		if (connection.isServer()) {
		    mediator =
			connection.serverRequestMapGet(header.getRequestId());
		} else {
		    mediator = 
			connection.clientRequestMapGet(header.getRequestId());
		}
		if (mediator != null) {
		    inputObject = mediator.getInputObject();
		}
		// See 1.1 comments.
		if (inputObject == null) {
		    if (transportDebug()) {
			dprint(".FRAGMENT 1.2: id/"
			       + header.getRequestId()
			       + ": ++++DISCARDING++++: "
			       + header);
		    }
                    // need to release dispatchByteBuffer to pool if
                    // we are discarding
                    releaseByteBufferToPool();
		    return;
		}
		((CDRInputObject)inputObject)
		    .getBufferManager().processFragment(
                                     dispatchByteBuffer, header);

		// REVISIT: but if it is a server don't you have to remove the
		// stream from the map?
		if (! connection.isServer()) {
		    /* REVISIT
		     * No need to do anything.
		     * Should we mark that last was received?
		     if (! header.moreFragmentsToFollow()) {
		     // Last fragment.
		     }
		    */
		}
	    } finally {
		// NOTE: This *must* come after queing the fragment
		// when using the selector to ensure fragments stay in order.
		setWorkThenReadOrResumeSelect(header);
	    }
	} catch (Throwable t) {
	    if (transportDebug()) 
		dprint(".FRAGMENT 1.2: id/"
		       + header.getRequestId()
		       + ": !!ERROR!!: " 
		       + header, t);
	    // Mask the exception from thread.;
	} finally {
	    if (transportDebug()) dprint(".FRAGMENT 1.2<-: id/"
					 + header.getRequestId() 
					 + ": "
					 + header);
	}
    
public voidhandleInput(com.sun.corba.se.impl.protocol.giopmsgheaders.CancelRequestMessage header)

	try {
	    try {
		messageHeader = header;
		setInputObject();

		// REVISIT: Move these two to subcontract.
		inputObject.unmarshalHeader();

		if (transportDebug()) dprint(".CANCEL->: id/" 
					     + header.getRequestId() + ": "
					     + header.getGIOPVersion() + ": "
					     + header);

		processCancelRequest(header.getRequestId());
                releaseByteBufferToPool();
	    } finally {
		setWorkThenReadOrResumeSelect(header);
	    }
	} catch (Throwable t) {
	    if (transportDebug()) dprint(".CANCEL: id/"
					 + header.getRequestId()
					 + ": !!ERROR!!: " 
					 + header, t);
	    // Mask the exception from thread.;
	} finally {
	    if (transportDebug()) dprint(".CANCEL<-: id/" 
					 + header.getRequestId() + ": "
					 + header.getGIOPVersion() + ": "
					 + header);
	}
    
protected voidhandleLocateRequest(com.sun.corba.se.spi.protocol.CorbaMessageMediator messageMediator)

	ORB orb = (ORB)messageMediator.getBroker();
	LocateRequestMessage msg = (LocateRequestMessage)
	    messageMediator.getDispatchHeader();
	IOR ior = null;
	LocateReplyMessage reply = null;
	short addrDisp = -1; 

	try {
	    ((CDRInputObject)messageMediator.getInputObject()).unmarshalHeader();
	    CorbaServerRequestDispatcher sc = 
		msg.getObjectKey().getServerRequestDispatcher( orb ) ;
	    if (sc == null) {
		return;
	    }

	    ior = sc.locate(msg.getObjectKey());

	    if ( ior == null ) {
		reply = MessageBase.createLocateReply(
		            orb, msg.getGIOPVersion(),
			    msg.getEncodingVersion(), 
                            msg.getRequestId(),
			    LocateReplyMessage.OBJECT_HERE, null);

	    } else {
		reply = MessageBase.createLocateReply(
		            orb, msg.getGIOPVersion(),
			    msg.getEncodingVersion(),
                            msg.getRequestId(),
			    LocateReplyMessage.OBJECT_FORWARD, ior);
	    }
	    // REVISIT: Should we catch SystemExceptions?

	} catch (AddressingDispositionException ex) {

	    // create a response containing the expected target
	    // addressing disposition.
	    
	    reply = MessageBase.createLocateReply(
		        orb, msg.getGIOPVersion(),
			msg.getEncodingVersion(),
                        msg.getRequestId(),
			LocateReplyMessage.LOC_NEEDS_ADDRESSING_MODE, null);

	    addrDisp = ex.expectedAddrDisp();

	} catch (RequestCanceledException ex) {

	    return; // no need to send reply

	} catch ( Exception ex ) {

	    // REVISIT If exception is not OBJECT_NOT_EXIST, it should
	    // have a different reply

	    // This handles OBJECT_NOT_EXIST exceptions thrown in
	    // the subcontract or obj manager. Send back UNKNOWN_OBJECT.

	    reply = MessageBase.createLocateReply(
		        orb, msg.getGIOPVersion(),
			msg.getEncodingVersion(),
			msg.getRequestId(),
			LocateReplyMessage.UNKNOWN_OBJECT, null);
	}

	CDROutputObject outputObject =
	    createAppropriateOutputObject(messageMediator,
					  msg, reply);
	messageMediator.setOutputObject(outputObject);
	outputObject.setMessageMediator(messageMediator);

	reply.write(outputObject);
	// outputObject.setMessage(reply); // REVISIT - not necessary
	if (ior != null) {
	    ior.write(outputObject);
	}
	if (addrDisp != -1) {
	    AddressingDispositionHelper.write(outputObject, addrDisp);
	}
    
public booleanhandleRequest(com.sun.corba.se.pept.protocol.MessageMediator messageMediator)


    ////////////////////////////////////////////////////
    //
    // pept.protocol.ProtocolHandler
    //

       
    
	try {
	    dispatchHeader.callback(this);
	} catch (IOException e) {
	    // REVISIT - this should be handled internally.
	    ;
	}
	return isThreadDone;
    
public voidhandleRequest(com.sun.corba.se.impl.protocol.giopmsgheaders.RequestMessage msg, com.sun.corba.se.spi.protocol.CorbaMessageMediator messageMediator)

	try {
	    beginRequest(messageMediator);
	    try {
		handleRequestRequest(messageMediator);
		if (messageMediator.isOneWay()) {
		    return;
		}
	    } catch (Throwable t) {
		if (messageMediator.isOneWay()) {
		    return;
		}
		handleThrowableDuringServerDispatch(
                    messageMediator, t, CompletionStatus.COMPLETED_MAYBE);
	    }
	    sendResponse(messageMediator);
        } catch (Throwable t) {
	    dispatchError(messageMediator, "RequestMessage", t);
	} finally {
	    endRequest(messageMediator);
	}
    
public voidhandleRequest(com.sun.corba.se.impl.protocol.giopmsgheaders.LocateRequestMessage msg, com.sun.corba.se.spi.protocol.CorbaMessageMediator messageMediator)

	try {
	    beginRequest(messageMediator);
	    try {
		handleLocateRequest(messageMediator);
	    } catch (Throwable t) {
		handleThrowableDuringServerDispatch(
	            messageMediator, t, CompletionStatus.COMPLETED_MAYBE);
	    }
	    sendResponse(messageMediator);
        } catch (Throwable t) {
	    dispatchError(messageMediator, "LocateRequestMessage", t);
	} finally {
	    endRequest(messageMediator);
	}
    
protected voidhandleRequestRequest(com.sun.corba.se.spi.protocol.CorbaMessageMediator messageMediator)

	// Does nothing if already unmarshaled.
	((CDRInputObject)messageMediator.getInputObject()).unmarshalHeader();

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

	ObjectKey okey = messageMediator.getObjectKey();
        if (orb.subcontractDebugFlag) {
	    ObjectKeyTemplate oktemp = okey.getTemplate() ;
	    dprint( ".handleRequest: " + opAndId(messageMediator)
		    + ": dispatching to scid: " + oktemp.getSubcontractId());
	}

	CorbaServerRequestDispatcher sc = okey.getServerRequestDispatcher(orb);

	if (orb.subcontractDebugFlag) {
	    dprint(".handleRequest: " + opAndId(messageMediator)
		   + ": dispatching to sc: " + sc);
	}

	if (sc == null) {
	    throw wrapper.noServerScInDispatch() ;
	}

	// NOTE:
	// This is necessary so mediator can act as ResponseHandler
	// and pass necessary info to response constructors located
	// in the subcontract.
	// REVISIT - same class right now.
	//messageMediator.setProtocolHandler(this);

        try {
            orb.startingDispatch();
	    sc.dispatch(messageMediator);
        } finally {
            orb.finishedDispatch();
        }
    
public voidhandleThrowableDuringServerDispatch(com.sun.corba.se.spi.protocol.CorbaMessageMediator messageMediator, java.lang.Throwable throwable, org.omg.CORBA.CompletionStatus completionStatus)

	if (((ORB)messageMediator.getBroker()).subcontractDebugFlag) {
	    dprint(".handleThrowableDuringServerDispatch: "
		   + opAndId(messageMediator) + ": "
		   + throwable);
	}

	// If we haven't unmarshaled the header, we probably don't
	// have enough information to even send back a reply.

	// REVISIT
	// Cannot do this check.  When target addressing disposition does
	// not match (during header unmarshaling) it throws an exception
	// to be handled here.
	/*
	if (! ((CDRInputObject)messageMediator.getInputObject())
	    .unmarshaledHeader()) {
	    return;
	}
	*/
	handleThrowableDuringServerDispatch(messageMediator, 
					    throwable,
					    completionStatus,
					    1);
    
protected voidhandleThrowableDuringServerDispatch(com.sun.corba.se.spi.protocol.CorbaMessageMediator messageMediator, java.lang.Throwable throwable, org.omg.CORBA.CompletionStatus completionStatus, int iteration)

	if (iteration > 10) {
	    if (((ORB)messageMediator.getBroker()).subcontractDebugFlag) {
		dprint(".handleThrowableDuringServerDispatch: " 
		       + opAndId(messageMediator)
		       + ": cannot handle: "
		       + throwable);
	    }

	    // REVISIT - should we close connection?
	    RuntimeException rte =
		new RuntimeException("handleThrowableDuringServerDispatch: " +
				     "cannot create response.");
	    rte.initCause(throwable);
	    throw rte;
	}

	try {
	    if (throwable instanceof ForwardException) {
		ForwardException fex = (ForwardException)throwable ;
		createLocationForward( messageMediator, fex.getIOR(), null ) ;
		return;
	    }

	    if (throwable instanceof AddressingDispositionException) {
		handleAddressingDisposition(
                    messageMediator,
		    (AddressingDispositionException)throwable);
		return;
	    } 

	    // Else.

	    SystemException sex = 
		convertThrowableToSystemException(throwable, completionStatus);

	    createSystemExceptionResponse(messageMediator, sex, null);
	    return;

	} catch (Throwable throwable2) {

	    // User code (e.g., postinvoke, interceptors) may change
	    // the exception, so we end up back here.
	    // Report the changed exception.

	    handleThrowableDuringServerDispatch(messageMediator,
						throwable2,
						completionStatus,
						iteration + 1);
	    return;
	}
    
public voidinitializeMessage()

	getRequestHeader().write(outputObject);
    
public booleanisDIIRequest()

	return diiRequest != null;
    
public booleanisDifferentAddrDispositionRequestedReply()

	return replyHeader.getReplyStatus() == ReplyMessage.NEEDS_ADDRESSING_MODE;
    
public booleanisLocationForwardReply()

	return ( (replyHeader.getReplyStatus() == ReplyMessage.LOCATION_FORWARD) ||
		 (replyHeader.getReplyStatus() == ReplyMessage.LOCATION_FORWARD_PERM) );
	//return replyHeader.getReplyStatus() == ReplyMessage.LOCATION_FORWARD;
    
public booleanisOneWay()

	return ! getRequestHeader().isResponseExpected();
    
public booleanisSystemExceptionReply()

	return replyHeader.getReplyStatus() == ReplyMessage.SYSTEM_EXCEPTION;
    
public booleanisUserExceptionReply()

	return replyHeader.getReplyStatus() == ReplyMessage.USER_EXCEPTION;
    
protected java.lang.StringopAndId(com.sun.corba.se.spi.protocol.CorbaMessageMediator mediator)

	return ORBUtility.operationNameAndRequestId(mediator);
    
private final voidprocessCancelRequest(int cancelReqId)


        // The GIOP version of CancelRequest does not matter, since
        // CancelRequest_1_0 could be sent to cancel a request which
        // has a different GIOP version.

        /*
         * CancelRequest processing logic :
         *
         *  - find the request with matching requestId
         *
         *  - call cancelProcessing() in BufferManagerRead [BMR]
         *
         *  - the hope is that worker thread would call BMR.underflow()
         *    to wait for more fragments to come in. When BMR.underflow() is
         *    called, if a CancelRequest had already arrived,  
	 *    the worker thread would throw ThreadDeath,
         *    else the thread would wait to be notified of the
         *    arrival of a new fragment or CancelRequest. Upon notification,
         *    the woken up thread would check to see if a CancelRequest had
         *    arrived and if so throw a ThreadDeath or it will continue to
         *    process the received fragment.
         *
         *  - if all the fragments had been received prior to CancelRequest
         *    then the worker thread would never block in BMR.underflow().
         *    So, setting the abort flag in BMR has no effect. The request
         *    processing will complete normally.
         *
         *  - in the case where the server has received enough fragments to 
	 *    start processing the request and the server sends out 
	 *    an early reply. In such a case if the CancelRequest arrives 
	 *    after the reply has been sent, it has no effect.
         */

        if (!connection.isServer()) {
	    return; // we do not support bi-directional giop yet, ignore.
        }

        // Try to get hold of the InputStream buffer.
        // In the case of 1.0 requests there is no way to get hold of
        // InputStream. Try out the 1.1 and 1.2 cases.

        // was the request 1.2 ?
	MessageMediator mediator = connection.serverRequestMapGet(cancelReqId);
	int requestId ;
        if (mediator == null) { 
	    // was the request 1.1 ?
	    mediator = connection.serverRequest_1_1_Get();
            if (mediator == null) {
		// XXX log this!
                // either the request was 1.0
                // or an early reply has already been sent
                // or request processing is over
                // or its a spurious CancelRequest
                return; // do nothing.
            }

	    requestId = ((CorbaMessageMediator) mediator).getRequestId();

            if (requestId != cancelReqId) {
                // A spurious 1.1 CancelRequest has been received.
		// XXX log this!
                return; // do nothing
            }

	    if (requestId == 0) { // special case
		// XXX log this
		// this means that
		// 1. the 1.1 requests' requestId has not been received
		//    i.e., a CancelRequest was received even before the
		//    1.1 request was received. The spec disallows this.
		// 2. or the 1.1 request has a requestId 0.
		//
		// It is a little tricky to distinguish these two. So, be
		// conservative and do not cancel the request. Downside is that
		// 1.1 requests with requestId of 0 will never be cancelled.
		return; // do nothing
	    }
	} else {
	    requestId = ((CorbaMessageMediator) mediator).getRequestId();
	}

	Message msg = ((CorbaMessageMediator)mediator).getRequestHeader();
	if (msg.getType() != Message.GIOPRequest) {
	    // Any mediator obtained here should only ever be for a GIOP
	    // request.
	    wrapper.badMessageTypeForCancel() ;	
	}

	// At this point we have a valid message mediator that contains
	// a valid requestId.

        // at this point we have chosen a request to be cancelled. But we
        // do not know if the target object's method has been invoked or not.
        // Request input stream being available simply means that the request
        // processing is not over yet. simply set the abort flag in the
        // BMRS and hope that the worker thread would notice it (this can
        // happen only if the request stream is being unmarshalled and the
        // target's method has not been invoked yet). This guarantees
        // that the requests which have been dispatched to the
        // target's method will never be cancelled.

        BufferManagerReadStream bufferManager = (BufferManagerReadStream)
	    ((CDRInputObject)mediator.getInputObject()).getBufferManager();
        bufferManager.cancelProcessing(cancelReqId);
    
private voidreleaseByteBufferToPool()

        if (dispatchByteBuffer != null) {
            orb.getByteBufferPool().releaseByteBuffer(dispatchByteBuffer);
            if (transportDebug()) {
                int bbId = System.identityHashCode(dispatchByteBuffer);
                StringBuffer sb = new StringBuffer();
                sb.append(".handleInput: releasing ByteBuffer (" + bbId + 
                          ") to ByteBufferPool");
                dprint(sb.toString());
             }
        }
    
private voidresumeSelect(com.sun.corba.se.impl.protocol.giopmsgheaders.Message header)

	// NOTE: VERY IMPORTANT:
	// Only participate in select after getting to the point
	// that proper serialization of fragments is ensured.

	if (transportDebug()) {
	    dprint(".resumeSelect:->");
	    // REVISIT: not-OO:
	    String requestId = "?";
	    if (header instanceof RequestMessage) {
		requestId = 
		    new Integer(((RequestMessage)header)
				.getRequestId()).toString();
	    } else if (header instanceof ReplyMessage) {
		requestId = 
		    new Integer(((ReplyMessage)header)
				.getRequestId()).toString();
	    } else if (header instanceof FragmentMessage_1_2) {
		requestId = 
		    new Integer(((FragmentMessage_1_2)header)
				.getRequestId()).toString();
	    }
	    dprint(".resumeSelect: id/" 
		   + requestId
		   + " " + getConnection()
		   );

	}

	// IMPORTANT: To avoid bug (4953599), we force the Thread that does the NIO select
	// to also do the enable/disable of Ops using SelectionKey.interestOps(Ops of Interest).
	// Otherwise, the SelectionKey.interestOps(Ops of Interest) may block indefinitely in
	// this thread.
	EventHandler eventHandler = getConnection().getEventHandler();
	orb.getTransportManager().getSelector(0).registerInterestOps(eventHandler);

	if (transportDebug()) {
	    dprint(".resumeSelect:<-");
	}
    
protected voidrunInterceptors(com.sun.corba.se.spi.protocol.CorbaMessageMediator messageMediator, com.sun.corba.se.impl.protocol.giopmsgheaders.ReplyMessage reply)

	if( messageMediator.executePIInResponseConstructor() ) {
	    // Invoke server request ending interception points (send_*):
	    // Note: this may end up with a SystemException or an internal
	    // Runtime ForwardRequest
	    ((ORB)messageMediator.getBroker()).getPIHandler().
		invokeServerPIEndingPoint( reply );

	    // Note this will be executed even if a ForwardRequest or 
	    // SystemException is thrown by a Portable Interceptors ending 
	    // point since we end up in this constructor again anyway.
	    ((ORB)messageMediator.getBroker()).getPIHandler().
		cleanupServerPIRequest();

	    // See createSystemExceptionResponse for why this is necesary.
	    messageMediator.setExecutePIInResponseConstructor(false);
	}
    
protected voidrunRemoveThreadInfo(com.sun.corba.se.spi.protocol.CorbaMessageMediator messageMediator)

	// Once you get here then the final reply is available (i.e.,
	// postinvoke and interceptors have completed.
	if (messageMediator.executeRemoveThreadInfoInResponseConstructor()) {
	    messageMediator.setExecuteRemoveThreadInfoInResponseConstructor(false);
	    ((ORB)messageMediator.getBroker()).popInvocationInfo() ;
	}
    
protected voidrunServantPostInvoke(com.sun.corba.se.spi.protocol.CorbaMessageMediator messageMediator)

	// Run ServantLocator::postinvoke.  This may cause a SystemException
	// which will throw out of the constructor and return later
	// to construct a reply for that exception.  The internal logic
	// of returnServant makes sure that postinvoke is only called once.
	// REVISIT: instead of instanceof, put method on all orbs.
	ORB orb = null;
	// This flag is to deal with BootstrapServer use of reply streams,
	// with ServerRequestDispatcher's use of reply streams, etc.
	if (messageMediator.executeReturnServantInResponseConstructor()) {
	    // It is possible to get marshaling errors in the skeleton after
	    // postinvoke has completed.  We must set this to false so that
	    // when the error exception reply is constructed we don't try
	    // to incorrectly access poa current (which will be the wrong
	    // one or an empty stack.
	    messageMediator.setExecuteReturnServantInResponseConstructor(false);
	    messageMediator.setExecuteRemoveThreadInfoInResponseConstructor(true);

	    try {
		orb = (ORB)messageMediator.getBroker();
		OAInvocationInfo info = orb.peekInvocationInfo() ;
		ObjectAdapter oa = info.oa();
		try {
		    oa.returnServant() ;
		} catch (Throwable thr) {
		    wrapper.unexpectedException( thr ) ;

		    if (thr instanceof Error)
			throw (Error)thr ;
		    else if (thr instanceof RuntimeException)
			throw (RuntimeException)thr ;
		} finally {
		    oa.exit();
		}
	    } catch (EmptyStackException ese) {
		throw wrapper.emptyStackRunServantPostInvoke( ese ) ;
	    }
	}
    
public voidsendCancelRequestIfFinalFragmentNotSent()

	if ((!sentFullMessage()) && sentFragment() && 
	    (!cancelRequestAlreadySent))
        {
	    try {
		if (orb.subcontractDebugFlag) {
		    dprint(".sendCancelRequestIfFinalFragmentNotSent->: " 
			   + opAndId(this));
		}
		connection.sendCancelRequestWithLock(getGIOPVersion(),
						     getRequestId());
		// Case: first a location forward, then a marshaling 
		// exception (e.g., non-serializable object).  Only
		// send cancel once.
		cancelRequestAlreadySent = true;
	    } catch (IOException e) {
		if (orb.subcontractDebugFlag) {
		    dprint(".sendCancelRequestIfFinalFragmentNotSent: !ERROR : " + opAndId(this),
			   e);
		}

		// REVISIT: we could attempt to send a final incomplete
		// fragment in this case.
		throw interceptorWrapper.ioexceptionDuringCancelRequest(
		    CompletionStatus.COMPLETED_MAYBE, e );
	    } finally {
		if (orb.subcontractDebugFlag) {
		    dprint(".sendCancelRequestIfFinalFragmentNotSent<-: "
			   + opAndId(this));
		}
	    }
	}
    
private voidsendResponse(com.sun.corba.se.spi.protocol.CorbaMessageMediator messageMediator)

	if (orb.subcontractDebugFlag) {
	    dprint(".handleRequest: " + opAndId(messageMediator) 
		   + ": sending response");
	}
	// REVISIT - type and location
	CDROutputObject outputObject = (CDROutputObject)
	    messageMediator.getOutputObject();
	if (outputObject != null) {
	    // REVISIT - can be null for TRANSIENT below.
	    outputObject.finishSendingMessage();
	}
    
public booleansentFragment()

	return outputObject.getBufferManager().sentFragment();
    
public booleansentFullMessage()

	return outputObject.getBufferManager().sentFullMessage();
    
public voidsetDIIException(java.lang.Exception exception)

	diiRequest.env().exception(exception);
    
public voidsetDIIInfo(org.omg.CORBA.Request diiRequest)

	this.diiRequest = diiRequest;
    
public voidsetDispatchBuffer(java.nio.ByteBuffer byteBuffer)

	dispatchByteBuffer = byteBuffer;
    
public voidsetDispatchHeader(com.sun.corba.se.impl.protocol.giopmsgheaders.Message msg)

	dispatchHeader = msg;
    
public voidsetExecutePIInResponseConstructor(boolean b)

	_executePIInResponseConstructor = b;
    
public voidsetExecuteRemoveThreadInfoInResponseConstructor(boolean b)

	_executeRemoveThreadInfoInResponseConstructor = b;
    
public voidsetExecuteReturnServantInResponseConstructor(boolean b)

	_executeReturnServantInResponseConstructor = b;
    
public voidsetInputObject(com.sun.corba.se.pept.encoding.InputObject inputObject)

	this.inputObject = (CDRInputObject) inputObject;
    
private voidsetInputObject()

	// REVISIT: refactor createInputObject (and createMessageMediator)
	// into base PlugInFactory.  Get via connection (either ContactInfo
	// or Acceptor).
	if (getConnection().getContactInfo() != null) {
	    inputObject = (CDRInputObject)
		getConnection().getContactInfo()
		.createInputObject(orb, this);
	} else if (getConnection().getAcceptor() != null) {
	    inputObject = (CDRInputObject)
		getConnection().getAcceptor()
		.createInputObject(orb, this);
	} else {
	    throw new RuntimeException("CorbaMessageMediatorImpl.setInputObject");
	}
	inputObject.setMessageMediator(this);
	setInputObject(inputObject);
    
public voidsetOutputObject(com.sun.corba.se.pept.encoding.OutputObject outputObject)

	this.outputObject = (CDROutputObject) outputObject;
    
public voidsetProtocolHandler(com.sun.corba.se.spi.protocol.CorbaProtocolHandler protocolHandler)

	throw wrapper.methodShouldNotBeCalled() ;
    
public voidsetReplyExceptionDetailMessage(java.lang.String message)

	replyExceptionDetailMessage = message;
    
public voidsetReplyHeader(com.sun.corba.se.impl.protocol.giopmsgheaders.LocateReplyOrReplyMessage header)

	this.replyHeader = header;
	this.replyIOR = header.getIOR(); // REVISIT - need separate field?
    
private voidsetWorkThenPoolOrResumeSelect(com.sun.corba.se.impl.protocol.giopmsgheaders.Message header)

	if (getConnection().getEventHandler().shouldUseSelectThreadToWait()) {
	    resumeSelect(header);
	} else {
	    // Leader/Follower when using reader thread.
	    // When this thread is done working it will go back in pool.
	
	    isThreadDone = true;

	    // First unregister current registration.
	    orb.getTransportManager().getSelector(0)
		.unregisterForEvent(getConnection().getEventHandler());
	    // Have another thread become the reader.
	    orb.getTransportManager().getSelector(0)
		.registerForEvent(getConnection().getEventHandler());
	}
    
private voidsetWorkThenReadOrResumeSelect(com.sun.corba.se.impl.protocol.giopmsgheaders.Message header)

	if (getConnection().getEventHandler().shouldUseSelectThreadToWait()) {
	    resumeSelect(header);
	} else {
	    // When using reader thread then wen this thread is 
	    // done working it will continue reading.
	    isThreadDone = false;
	}
    
private voidsignalResponseReceived()

	// This will end up using the MessageMediator associated with
	// the original request instead of the current mediator (which
	// need to be constructed to hold the dispatchBuffer and connection).
	connection.getResponseWaitingRoom()
	    .responseReceived((InputObject)inputObject);
    
private voidthrowNotImplemented()

	isThreadDone = false;
	throwNotImplemented("");
    
private voidthrowNotImplemented(java.lang.String msg)

	throw new RuntimeException("CorbaMessageMediatorImpl: not implemented " + msg);
    
private booleantransportDebug()

	return orb.transportDebugFlag;
    
public java.lang.ExceptionunmarshalDIIUserException(java.lang.String repoId, org.omg.CORBA_2_3.portable.InputStream is)

	if (! isDIIRequest()) {
	    return null;
	}

	ExceptionList _exceptions = diiRequest.exceptions();

	try {
	    // Find the typecode for the exception
	    for (int i=0; i<_exceptions.count() ; i++) {
		TypeCode tc = _exceptions.item(i);
		if ( tc.id().equals(repoId) ) {
		    // Since we dont have the actual user exception
		    // class, the spec says we have to create an
		    // UnknownUserException and put it in the
		    // environment.
		    Any eany = orb.create_any();
		    eany.read_value(is, (TypeCode)tc);

		    return new UnknownUserException(eany);
		}
	    }
	} catch (Exception b) {
	    throw wrapper.unexpectedDiiException(b);
	}

	// must be a truly unknown exception
	return wrapper.unknownCorbaExc( CompletionStatus.COMPLETED_MAYBE); 
    
public com.sun.corba.se.pept.encoding.InputObjectwaitForResponse()

	if (getRequestHeader().isResponseExpected()) {
	    return connection.waitForResponse(this);
	}
	return null;