- /*
- * @(#)CorbaClientRequestDispatcherImpl.java 1.86 04/06/21
- *
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- */
-
- /*
- * Licensed Materials - Property of IBM
- * RMI-IIOP v1.0
- * Copyright IBM Corp. 1998 1999 All Rights Reserved
- *
- * US Government Users Restricted Rights - Use, duplication or
- * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
- */
-
- package com.sun.corba.se.impl.protocol;
-
- import java.io.IOException;
- import java.util.Iterator;
- import java.rmi.RemoteException;
-
- import javax.rmi.CORBA.Util;
- import javax.rmi.CORBA.Tie;
-
- import org.omg.CORBA.COMM_FAILURE;
- import org.omg.CORBA.INTERNAL;
- import org.omg.CORBA.SystemException;
- import org.omg.CORBA.Request;
- import org.omg.CORBA.NamedValue;
- import org.omg.CORBA.NVList;
- import org.omg.CORBA.Context;
- import org.omg.CORBA.ContextList;
- import org.omg.CORBA.ExceptionList;
- import org.omg.CORBA.TypeCode;
- import org.omg.CORBA.portable.RemarshalException;
- import org.omg.CORBA_2_3.portable.InputStream;
- import org.omg.CORBA_2_3.portable.OutputStream;
- import org.omg.CORBA.portable.Delegate;
- import org.omg.CORBA.portable.ServantObject;
- import org.omg.CORBA.portable.ApplicationException;
- import org.omg.CORBA.portable.UnknownException;
- import org.omg.IOP.ExceptionDetailMessage;
- import org.omg.IOP.TAG_CODE_SETS;
-
- import com.sun.org.omg.SendingContext.CodeBase;
-
- import com.sun.corba.se.pept.broker.Broker;
- import com.sun.corba.se.pept.encoding.InputObject;
- import com.sun.corba.se.pept.encoding.OutputObject;
- import com.sun.corba.se.pept.protocol.ClientRequestDispatcher;
- import com.sun.corba.se.pept.protocol.MessageMediator;
- import com.sun.corba.se.pept.transport.Connection;
- import com.sun.corba.se.pept.transport.OutboundConnectionCache;
- import com.sun.corba.se.pept.transport.ContactInfo;
-
- import com.sun.corba.se.spi.ior.IOR;
- import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
- import com.sun.corba.se.spi.ior.iiop.IIOPProfileTemplate;
- import com.sun.corba.se.spi.ior.iiop.CodeSetsComponent;
- import com.sun.corba.se.spi.oa.OAInvocationInfo;
- import com.sun.corba.se.spi.oa.ObjectAdapterFactory;
- import com.sun.corba.se.spi.orb.ORB;
- import com.sun.corba.se.spi.orb.ORBVersion;
- import com.sun.corba.se.spi.orb.ORBVersionFactory;
- import com.sun.corba.se.spi.protocol.CorbaMessageMediator;
- import com.sun.corba.se.spi.protocol.RequestDispatcherRegistry;
- import com.sun.corba.se.spi.transport.CorbaContactInfo ;
- import com.sun.corba.se.spi.transport.CorbaContactInfoList ;
- import com.sun.corba.se.spi.transport.CorbaContactInfoListIterator ;
- import com.sun.corba.se.spi.transport.CorbaConnection;
- import com.sun.corba.se.spi.logging.CORBALogDomains;
-
- import com.sun.corba.se.spi.servicecontext.MaxStreamFormatVersionServiceContext;
- import com.sun.corba.se.spi.servicecontext.ServiceContext;
- import com.sun.corba.se.spi.servicecontext.ServiceContexts;
- import com.sun.corba.se.spi.servicecontext.UEInfoServiceContext;
- import com.sun.corba.se.spi.servicecontext.CodeSetServiceContext;
- import com.sun.corba.se.spi.servicecontext.SendingContextServiceContext;
- import com.sun.corba.se.spi.servicecontext.ORBVersionServiceContext;
- import com.sun.corba.se.spi.servicecontext.MaxStreamFormatVersionServiceContext;
- import com.sun.corba.se.spi.servicecontext.UnknownServiceContext;
-
- import com.sun.corba.se.impl.encoding.CDRInputObject;
- import com.sun.corba.se.impl.encoding.CodeSetComponentInfo;
- import com.sun.corba.se.impl.encoding.CodeSetConversion;
- import com.sun.corba.se.impl.encoding.EncapsInputStream;
- import com.sun.corba.se.impl.encoding.MarshalOutputStream;
- import com.sun.corba.se.impl.encoding.MarshalInputStream;
- import com.sun.corba.se.impl.logging.ORBUtilSystemException;
- import com.sun.corba.se.impl.orbutil.ORBUtility;
- import com.sun.corba.se.impl.orbutil.ORBConstants;
- import com.sun.corba.se.impl.protocol.giopmsgheaders.ReplyMessage;
- import com.sun.corba.se.impl.protocol.giopmsgheaders.KeyAddr;
- import com.sun.corba.se.impl.protocol.giopmsgheaders.ProfileAddr;
- import com.sun.corba.se.impl.protocol.giopmsgheaders.ReferenceAddr;
- import com.sun.corba.se.impl.transport.CorbaContactInfoListIteratorImpl;
- import com.sun.corba.se.impl.util.JDKBridge;
-
- /**
- * ClientDelegate is the RMI client-side subcontract or representation
- * It implements RMI delegate as well as our internal ClientRequestDispatcher
- * interface.
- */
- public class CorbaClientRequestDispatcherImpl
- implements
- ClientRequestDispatcher
- {
- // Used for locking
- private Object lock = new Object();
-
- public OutputObject beginRequest(Object self, String opName,
- boolean isOneWay, ContactInfo contactInfo)
- {
- ORB orb = null;
- try {
- CorbaContactInfo corbaContactInfo = (CorbaContactInfo) contactInfo;
- orb = (ORB)contactInfo.getBroker();
-
- if (orb.subcontractDebugFlag) {
- dprint(".beginRequest->: op/" + opName);
- }
-
- //
- // Portable Interceptor initialization.
- //
-
- orb.getPIHandler().initiateClientPIRequest( false );
-
- //
- // Connection.
- //
-
- CorbaConnection connection = null;
-
- // This locking is done so that multiple connections are not created
- // for the same endpoint
- synchronized (lock) {
- if (contactInfo.isConnectionBased()) {
- if (contactInfo.shouldCacheConnection()) {
- connection = (CorbaConnection)
- orb.getTransportManager()
- .getOutboundConnectionCache(contactInfo).get(contactInfo);
- }
- if (connection != null) {
- if (orb.subcontractDebugFlag) {
- dprint(".beginRequest: op/" + opName
- + ": Using cached connection: " + connection);
- }
- } else {
- try {
- connection = (CorbaConnection)
- contactInfo.createConnection();
- if (orb.subcontractDebugFlag) {
- dprint(".beginRequest: op/" + opName
- + ": Using created connection: " + connection);
- }
- } catch (RuntimeException e) {
- if (orb.subcontractDebugFlag) {
- dprint(".beginRequest: op/" + opName
- + ": failed to create connection: " + e);
- }
- // REVISIT: this part similar to marshalingComplete below.
- boolean retry = getContactInfoListIterator(orb)
- .reportException(contactInfo, e);
- // REVISIT:
- // this part similar to Remarshal in this method below
- if (retry) {
- if(getContactInfoListIterator(orb).hasNext()) {
- contactInfo = (ContactInfo)
- getContactInfoListIterator(orb).next();
- return beginRequest(self, opName,
- isOneWay, contactInfo);
- } else {
- throw e;
- }
- } else {
- throw e;
- }
- }
- if (connection.shouldRegisterReadEvent()) {
- // REVISIT: cast
- orb.getTransportManager().getSelector(0)
- .registerForEvent(connection.getEventHandler());
- connection.setState("ESTABLISHED");
- }
- // Do not do connection reclaim here since the connections
- // are marked in use by registerWaiter() call and since this
- // call happens later do it after that.
- if (contactInfo.shouldCacheConnection()) {
- OutboundConnectionCache connectionCache =
- orb.getTransportManager()
- .getOutboundConnectionCache(contactInfo);
- connectionCache.stampTime(connection);
- connectionCache.put(contactInfo, connection);
- // connectionCache.reclaim();
- }
- }
- }
- }
-
- CorbaMessageMediator messageMediator = (CorbaMessageMediator)
- contactInfo.createMessageMediator(
- orb, contactInfo, connection, opName, isOneWay);
- if (orb.subcontractDebugFlag) {
- dprint(".beginRequest: " + opAndId(messageMediator)
- + ": created message mediator: " + messageMediator);
- }
-
- // NOTE: Thread data so we can get the mediator in release reply
- // in order to remove the waiter in CorbaConnection.
- // We cannot depend on obtaining information in releaseReply
- // via its InputStream argument since, on certain errors
- // (e.g., client marshaling errors), the stream may be null.
- // Likewise for releaseReply "self".
- // NOTE: This must be done before initializing the message since
- // that may start sending fragments which may end up in "early"
- // replies or client marshaling exceptions.
-
- orb.getInvocationInfo().setMessageMediator(messageMediator);
-
- if (connection != null && connection.getCodeSetContext() == null) {
- performCodeSetNegotiation(messageMediator);
- }
-
- addServiceContexts(messageMediator);
-
- OutputObject outputObject =
- contactInfo.createOutputObject(messageMediator);
- if (orb.subcontractDebugFlag) {
- dprint(".beginRequest: " + opAndId(messageMediator)
- + ": created output object: " + outputObject);
- }
-
-
- // NOTE: Not necessary for oneways, but useful for debugging.
- // This must be done BEFORE message initialization since fragments
- // may be sent at that time.
- registerWaiter(messageMediator);
-
- // Do connection reclaim now
- synchronized (lock) {
- if (contactInfo.isConnectionBased()) {
- if (contactInfo.shouldCacheConnection()) {
- OutboundConnectionCache connectionCache =
- orb.getTransportManager()
- .getOutboundConnectionCache(contactInfo);
- connectionCache.reclaim();
- }
- }
- }
-
- orb.getPIHandler().setClientPIInfo(messageMediator);
- try {
- // This MUST come before message is initialized so
- // service contexts may be added by PI because
- // initial fragments may be sent during message initialization.
- orb.getPIHandler().invokeClientPIStartingPoint();
- } catch( RemarshalException e ) {
- if (orb.subcontractDebugFlag) {
- dprint(".beginRequest: " + opAndId(messageMediator)
- + ": Remarshal");
- }
-
- // NOTE: We get here because an interceptor raised ForwardRequest
- // and updated the IOR/Iterator. Since we have a fresh iterator
- // hasNext should succeed.
-
- // REVISIT: We should feed ALL interceptor exceptions to
- // iterator.reportException so it can determine if it wants
- // to retry. Right now, SystemExceptions will flow to the
- // client code.
-
- // REVISIT:
- // This assumes that interceptors update
- // ContactInfoList outside of subcontract.
- // Want to move that update to here.
- if (getContactInfoListIterator(orb).hasNext()) {
- contactInfo = (ContactInfo)
- getContactInfoListIterator(orb).next();
- return beginRequest(self, opName, isOneWay, contactInfo);
- } else {
- ORBUtilSystemException wrapper =
- ORBUtilSystemException.get(orb,
- CORBALogDomains.RPC_PROTOCOL);
- throw wrapper.remarshalWithNowhereToGo();
- }
- }
-
- messageMediator.initializeMessage();
- if (orb.subcontractDebugFlag) {
- dprint(".beginRequest: " + opAndId(messageMediator)
- + ": initialized message");
- }
-
- return outputObject;
-
- } finally {
- if (orb.subcontractDebugFlag) {
- dprint(".beginRequest<-: op/" + opName);
- }
- }
- }
-
- public InputObject marshalingComplete(java.lang.Object self,
- OutputObject outputObject)
- throws
- ApplicationException,
- org.omg.CORBA.portable.RemarshalException
- {
- ORB orb = null;
- CorbaMessageMediator messageMediator = null;
- try {
- messageMediator = (CorbaMessageMediator)
- outputObject.getMessageMediator();
-
- orb = (ORB) messageMediator.getBroker();
-
- if (orb.subcontractDebugFlag) {
- dprint(".marshalingComplete->: " + opAndId(messageMediator));
- }
-
- InputObject inputObject =
- marshalingComplete1(orb, messageMediator);
-
- return processResponse(orb, messageMediator, inputObject);
-
- } finally {
- if (orb.subcontractDebugFlag) {
- dprint(".marshalingComplete<-: " + opAndId(messageMediator));
- }
- }
- }
-
- public InputObject marshalingComplete1(
- ORB orb, CorbaMessageMediator messageMediator)
- throws
- ApplicationException,
- org.omg.CORBA.portable.RemarshalException
- {
- try {
- messageMediator.finishSendingRequest();
-
- if (orb.subcontractDebugFlag) {
- dprint(".marshalingComplete: " + opAndId(messageMediator)
- + ": finished sending request");
- }
-
- return messageMediator.waitForResponse();
-
- } catch (RuntimeException e) {
-
- if (orb.subcontractDebugFlag) {
- dprint(".marshalingComplete: " + opAndId(messageMediator)
- + ": exception: " + e.toString());
- }
-
- boolean retry =
- getContactInfoListIterator(orb)
- .reportException(messageMediator.getContactInfo(), e);
- if (retry) {
- // Must run interceptor end point before retrying.
- Exception newException =
- orb.getPIHandler().invokeClientPIEndingPoint(
- ReplyMessage.SYSTEM_EXCEPTION, e);
- if (newException == e) {
- continueOrThrowSystemOrRemarshal(messageMediator,
- new RemarshalException());
- } else {
- continueOrThrowSystemOrRemarshal(messageMediator,
- newException);
- }
- } else {
- // NOTE: Interceptor ending point will run in releaseReply.
- throw e;
- }
- return null; // for compiler
- }
- }
-
- protected InputObject processResponse(ORB orb,
- CorbaMessageMediator messageMediator,
- InputObject inputObject)
- throws
- ApplicationException,
- org.omg.CORBA.portable.RemarshalException
- {
- ORBUtilSystemException wrapper =
- ORBUtilSystemException.get( orb,
- CORBALogDomains.RPC_PROTOCOL ) ;
-
- if (orb.subcontractDebugFlag) {
- dprint(".processResponse: " + opAndId(messageMediator)
- + ": response received");
- }
-
- // We know for sure now that we've sent a message.
- // So OK to not send initial again.
- if (messageMediator.getConnection() != null) {
- ((CorbaConnection)messageMediator.getConnection())
- .setPostInitialContexts();
- }
-
- // NOTE: not necessary to set MessageMediator for PI.
- // It already has it.
-
- // Process the response.
-
- Exception exception = null;
-
- if (messageMediator.isOneWay()) {
- getContactInfoListIterator(orb)
- .reportSuccess(messageMediator.getContactInfo());
- // Invoke Portable Interceptors with receive_other
- exception = orb.getPIHandler().invokeClientPIEndingPoint(
- ReplyMessage.NO_EXCEPTION, exception );
- continueOrThrowSystemOrRemarshal(messageMediator, exception);
- return null;
- }
-
- consumeServiceContexts(orb, messageMediator);
-
- // Now that we have the service contexts processed and the
- // correct ORBVersion set, we must finish initializing the stream.
- // REVISIT - need interface for this operation.
- ((CDRInputObject)inputObject).performORBVersionSpecificInit();
-
- if (messageMediator.isSystemExceptionReply()) {
-
- SystemException se = messageMediator.getSystemExceptionReply();
-
- if (orb.subcontractDebugFlag) {
- dprint(".processResponse: " + opAndId(messageMediator)
- + ": received system exception: " + se);
- }
-
- boolean doRemarshal =
- getContactInfoListIterator(orb)
- .reportException(messageMediator.getContactInfo(), se);
-
- if (doRemarshal) {
-
- // Invoke Portable Interceptors with receive_exception:
- exception = orb.getPIHandler().invokeClientPIEndingPoint(
- ReplyMessage.SYSTEM_EXCEPTION, se );
-
- // If PI did not change the exception, throw a
- // Remarshal.
- if( se == exception ) {
- // exception = null is to maintain symmetry with
- // GenericPOAClientSC.
- exception = null;
- continueOrThrowSystemOrRemarshal(messageMediator,
- new RemarshalException());
- throw wrapper.statementNotReachable1() ;
- } else {
- // Otherwise, throw the exception PI wants thrown.
- continueOrThrowSystemOrRemarshal(messageMediator,
- exception);
- throw wrapper.statementNotReachable2() ;
- }
- }
-
- // No retry, so see if was unknown.
-
- ServiceContexts contexts =
- messageMediator.getReplyServiceContexts();
- if (contexts != null) {
- UEInfoServiceContext usc =
- (UEInfoServiceContext)
- contexts.get(UEInfoServiceContext.SERVICE_CONTEXT_ID);
-
- if (usc != null) {
- Throwable unknown = usc.getUE() ;
- UnknownException ue = new UnknownException(unknown);
-
- // Invoke Portable Interceptors with receive_exception:
- exception = orb.getPIHandler().invokeClientPIEndingPoint(
- ReplyMessage.SYSTEM_EXCEPTION, ue );
-
- continueOrThrowSystemOrRemarshal(messageMediator, exception);
- throw wrapper.statementNotReachable3() ;
- }
- }
-
- // It was not a comm failure nor unknown.
- // This is the general case.
-
- // Invoke Portable Interceptors with receive_exception:
- exception = orb.getPIHandler().invokeClientPIEndingPoint(
- ReplyMessage.SYSTEM_EXCEPTION, se );
-
- continueOrThrowSystemOrRemarshal(messageMediator, exception);
-
- // Note: We should never need to execute this line, but
- // we should assert in case exception is null somehow.
- throw wrapper.statementNotReachable4() ;
- } else if (messageMediator.isUserExceptionReply()) {
-
- if (orb.subcontractDebugFlag) {
- dprint(".processResponse: " + opAndId(messageMediator)
- + ": received user exception");
- }
-
- getContactInfoListIterator(orb)
- .reportSuccess(messageMediator.getContactInfo());
-
- String exceptionRepoId = peekUserExceptionId(inputObject);
- Exception newException = null;
-
- if (messageMediator.isDIIRequest()) {
- exception = messageMediator.unmarshalDIIUserException(
- exceptionRepoId, (InputStream)inputObject);
- newException = orb.getPIHandler().invokeClientPIEndingPoint(
- ReplyMessage.USER_EXCEPTION, exception );
- messageMediator.setDIIException(newException);
-
- } else {
- ApplicationException appException =
- new ApplicationException(
- exceptionRepoId,
- (org.omg.CORBA.portable.InputStream)inputObject);
- exception = appException;
- newException = orb.getPIHandler().invokeClientPIEndingPoint(
- ReplyMessage.USER_EXCEPTION, appException );
- }
-
- if (newException != exception) {
- continueOrThrowSystemOrRemarshal(messageMediator,newException);
- }
-
- if (newException instanceof ApplicationException) {
- throw (ApplicationException)newException;
- }
- // For DII:
- // This return will be ignored - already unmarshaled above.
- return inputObject;
-
- } else if (messageMediator.isLocationForwardReply()) {
-
- if (orb.subcontractDebugFlag) {
- dprint(".processResponse: " + opAndId(messageMediator)
- + ": received location forward");
- }
-
- // NOTE: Expects iterator to update target IOR
- getContactInfoListIterator(orb).reportRedirect(
- (CorbaContactInfo)messageMediator.getContactInfo(),
- messageMediator.getForwardedIOR());
-
- // Invoke Portable Interceptors with receive_other:
- Exception newException = orb.getPIHandler().invokeClientPIEndingPoint(
- ReplyMessage.LOCATION_FORWARD, null );
-
- if( !(newException instanceof RemarshalException) ) {
- exception = newException;
- }
-
- // If PI did not change exception, throw Remarshal, else
- // throw the exception PI wants thrown.
- // KMC: GenericPOAClientSC did not check exception != null
- if( exception != null ) {
- continueOrThrowSystemOrRemarshal(messageMediator, exception);
- }
- continueOrThrowSystemOrRemarshal(messageMediator,
- new RemarshalException());
- throw wrapper.statementNotReachable5() ;
-
- } else if (messageMediator.isDifferentAddrDispositionRequestedReply()){
-
- if (orb.subcontractDebugFlag) {
- dprint(".processResponse: " + opAndId(messageMediator)
- + ": received different addressing dispostion request");
- }
-
- // Set the desired target addressing disposition.
- getContactInfoListIterator(orb).reportAddrDispositionRetry(
- (CorbaContactInfo)messageMediator.getContactInfo(),
- messageMediator.getAddrDispositionReply());
-
- // Invoke Portable Interceptors with receive_other:
- Exception newException = orb.getPIHandler().invokeClientPIEndingPoint(
- ReplyMessage.NEEDS_ADDRESSING_MODE, null);
-
- // For consistency with corresponding code in GenericPOAClientSC:
- if( !(newException instanceof RemarshalException) ) {
- exception = newException;
- }
-
- // If PI did not change exception, throw Remarshal, else
- // throw the exception PI wants thrown.
- // KMC: GenericPOAClientSC did not include exception != null check
- if( exception != null ) {
- continueOrThrowSystemOrRemarshal(messageMediator, exception);
- }
- continueOrThrowSystemOrRemarshal(messageMediator,
- new RemarshalException());
- throw wrapper.statementNotReachable6() ;
- } else /* normal response */ {
-
- if (orb.subcontractDebugFlag) {
- dprint(".processResponse: " + opAndId(messageMediator)
- + ": received normal response");
- }
-
- getContactInfoListIterator(orb)
- .reportSuccess(messageMediator.getContactInfo());
-
- messageMediator.handleDIIReply((InputStream)inputObject);
-
- // Invoke Portable Interceptors with receive_reply:
- exception = orb.getPIHandler().invokeClientPIEndingPoint(
- ReplyMessage.NO_EXCEPTION, null );
-
- // Remember: not thrown if exception is null.
- continueOrThrowSystemOrRemarshal(messageMediator, exception);
-
- return inputObject;
- }
- }
-
- // Filters the given exception into a SystemException or a
- // RemarshalException and throws it. Assumes the given exception is
- // of one of these two types. This is a utility method for
- // the above invoke code which must do this numerous times.
- // If the exception is null, no exception is thrown.
- //
- // Note that this code is duplicated in GenericPOAClientSC.java
- protected void continueOrThrowSystemOrRemarshal(
- CorbaMessageMediator messageMediator, Exception exception)
- throws
- SystemException, RemarshalException
- {
-
- ORB orb = (ORB) messageMediator.getBroker();
-
- if( exception == null ) {
-
- // do nothing.
-
- } else if( exception instanceof RemarshalException ) {
-
- // REVISIT - unify with PI handling
- orb.getInvocationInfo().setIsRetryInvocation(true);
-
- // NOTE - We must unregister the waiter NOW for this request
- // since the retry will result in a new request id. Therefore
- // the old request id would be lost and we would have a memory
- // leak in the responseWaitingRoom.
- unregisterWaiter(orb);
-
- if (orb.subcontractDebugFlag) {
- dprint(".continueOrThrowSystemOrRemarshal: "
- + opAndId(messageMediator)
- + ": throwing Remarshal");
- }
-
- throw (RemarshalException)exception;
-
- } else {
-
- if (orb.subcontractDebugFlag) {
- dprint(".continueOrThrowSystemOrRemarshal: "
- + opAndId(messageMediator)
- + ": throwing sex:"
- + exception);
- }
-
- throw (SystemException)exception;
- }
- }
-
- protected CorbaContactInfoListIterator getContactInfoListIterator(ORB orb)
- {
- return (CorbaContactInfoListIterator)
- ((CorbaInvocationInfo)orb.getInvocationInfo())
- .getContactInfoListIterator();
- }
-
- protected void registerWaiter(CorbaMessageMediator messageMediator)
- {
- if (messageMediator.getConnection() != null) {
- messageMediator.getConnection().registerWaiter(messageMediator);
- }
- }
-
- protected void unregisterWaiter(ORB orb)
- {
- MessageMediator messageMediator =
- orb.getInvocationInfo().getMessageMediator();
- if (messageMediator!=null && messageMediator.getConnection() != null) {
- // REVISIT:
- // The messageMediator may be null if COMM_FAILURE before
- // it is created.
- messageMediator.getConnection().unregisterWaiter(messageMediator);
- }
- }
-
- protected void addServiceContexts(CorbaMessageMediator messageMediator)
- {
- ORB orb = (ORB)messageMediator.getBroker();
- CorbaConnection c = (CorbaConnection) messageMediator.getConnection();
- GIOPVersion giopVersion = messageMediator.getGIOPVersion();
-
- ServiceContexts contexts = messageMediator.getRequestServiceContexts();
-
- addCodeSetServiceContext(c, contexts, giopVersion);
-
- // Add the RMI-IIOP max stream format version
- // service context to every request. Once we have GIOP 1.3,
- // we could skip it since we now support version 2, but
- // probably safer to always send it.
- contexts.put(MaxStreamFormatVersionServiceContext.singleton);
-
- // ORBVersion servicecontext needs to be sent
- ORBVersionServiceContext ovsc = new ORBVersionServiceContext(
- ORBVersionFactory.getORBVersion() ) ;
- contexts.put( ovsc ) ;
-
- // NOTE : We only want to send the runtime context the first time
- if ((c != null) && !c.isPostInitialContexts()) {
- // Do not do c.setPostInitialContexts() here.
- // If a client interceptor send_request does a ForwardRequest
- // which ends up using the same connection then the service
- // context would not be sent.
- SendingContextServiceContext scsc =
- new SendingContextServiceContext( orb.getFVDCodeBaseIOR() ) ; //d11638
- contexts.put( scsc ) ;
- }
- }
-
- protected void consumeServiceContexts(ORB orb,
- CorbaMessageMediator messageMediator)
- {
- ServiceContexts ctxts = messageMediator.getReplyServiceContexts();
- ServiceContext sc ;
- ORBUtilSystemException wrapper = ORBUtilSystemException.get( orb,
- CORBALogDomains.RPC_PROTOCOL ) ;
-
- if (ctxts == null) {
- return; // no service context available, return gracefully.
- }
-
- sc = ctxts.get( SendingContextServiceContext.SERVICE_CONTEXT_ID ) ;
-
- if (sc != null) {
- SendingContextServiceContext scsc =
- (SendingContextServiceContext)sc ;
- IOR ior = scsc.getIOR() ;
-
- try {
- // set the codebase returned by the server
- if (messageMediator.getConnection() != null) {
- ((CorbaConnection)messageMediator.getConnection()).setCodeBaseIOR(ior);
- }
- } catch (ThreadDeath td) {
- throw td ;
- } catch (Throwable t) {
- throw wrapper.badStringifiedIor( t ) ;
- }
- }
-
- // see if the version subcontract is present, if yes, then set
- // the ORBversion
- sc = ctxts.get( ORBVersionServiceContext.SERVICE_CONTEXT_ID ) ;
-
- if (sc != null) {
- ORBVersionServiceContext ovsc =
- (ORBVersionServiceContext) sc;
-
- ORBVersion version = ovsc.getVersion();
- orb.setORBVersion( version ) ;
- }
-
- getExceptionDetailMessage(messageMediator, wrapper);
- }
-
- protected void getExceptionDetailMessage(
- CorbaMessageMediator messageMediator,
- ORBUtilSystemException wrapper)
- {
- ServiceContext sc = messageMediator.getReplyServiceContexts()
- .get(ExceptionDetailMessage.value);
- if (sc == null)
- return ;
-
- if (! (sc instanceof UnknownServiceContext)) {
- throw wrapper.badExceptionDetailMessageServiceContextType();
- }
- byte[] data = ((UnknownServiceContext)sc).getData();
- EncapsInputStream in =
- new EncapsInputStream((ORB)messageMediator.getBroker(),
- data, data.length);
- in.consumeEndian();
-
- String msg =
- "----------BEGIN server-side stack trace----------\n"
- + in.read_wstring() + "\n"
- + "----------END server-side stack trace----------";
-
- messageMediator.setReplyExceptionDetailMessage(msg);
- }
-
- public void endRequest(Broker broker, Object self, InputObject inputObject)
- {
- ORB orb = (ORB)broker ;
-
- try {
- if (orb.subcontractDebugFlag) {
- dprint(".endRequest->");
- }
-
- // Note: the inputObject may be null if an error occurs
- // in request or before _invoke returns.
- // Note: self may be null also (e.g., compiler generates null in stub).
-
- MessageMediator messageMediator =
- orb.getInvocationInfo().getMessageMediator();
- if (messageMediator != null)
- {
- if (messageMediator.getConnection() != null)
- {
- ((CorbaMessageMediator)messageMediator)
- .sendCancelRequestIfFinalFragmentNotSent();
- }
-
- // Release any outstanding NIO ByteBuffers to the ByteBufferPool
-
- InputObject inputObj = messageMediator.getInputObject();
- if (inputObj != null) {
- inputObj.close();
- }
-
- OutputObject outputObj = messageMediator.getOutputObject();
- if (outputObj != null) {
- outputObj.close();
- }
-
- }
-
- // XREVISIT NOTE - Assumes unregistering the waiter for
- // location forwards has already happened somewhere else.
- // The code below is only going to unregister the final successful
- // request.
-
- // NOTE: In the case of a recursive stack of endRequests in a
- // finally block (because of Remarshal) only the first call to
- // unregisterWaiter will remove the waiter. The rest will be
- // noops.
- unregisterWaiter(orb);
-
- // Invoke Portable Interceptors cleanup. This is done to handle
- // exceptions during stream marshaling. More generally, exceptions
- // that occur in the ORB after send_request (which includes
- // after returning from _request) before _invoke:
- orb.getPIHandler().cleanupClientPIRequest();
-
- // REVISIT: Early replies?
- } catch (IOException ex) {
- // See CDRInput/OutputObject.close() for more info.
- // This won't result in a Corba error if an IOException happens.
- if (orb.subcontractDebugFlag)
- {
- dprint(".endRequest: ignoring IOException - " + ex.toString());
- }
- } finally {
- if (orb.subcontractDebugFlag) {
- dprint(".endRequest<-");
- }
- }
- }
-
-
- protected void performCodeSetNegotiation(CorbaMessageMediator messageMediator)
- {
- CorbaConnection conn =
- (CorbaConnection) messageMediator.getConnection();
- IOR ior =
- ((CorbaContactInfo)messageMediator.getContactInfo())
- .getEffectiveTargetIOR();
- GIOPVersion giopVersion = messageMediator.getGIOPVersion();
-
- // XXX This seems to be a broken double checked locking idiom: FIX IT!
-
- // conn.getCodeSetContext() is null when no other requests have
- // been made on this connection to trigger code set negotation.
- if (conn != null &&
- conn.getCodeSetContext() == null &&
- !giopVersion.equals(GIOPVersion.V1_0)) {
-
- synchronized(conn) {
- // Double checking. Don't let any other
- // threads use this connection until the
- // code sets are straight.
- if (conn.getCodeSetContext() != null)
- return;
-
- // This only looks at the first code set component. If
- // there can be multiple locations with multiple code sets,
- // this requires more work.
- IIOPProfileTemplate temp =
- (IIOPProfileTemplate)ior.getProfile().
- getTaggedProfileTemplate();
- Iterator iter = temp.iteratorById(TAG_CODE_SETS.value);
- if (!iter.hasNext()) {
- // Didn't have a code set component. The default will
- // be to use ISO8859-1 for char data and throw an
- // exception if wchar data is used.
- return;
- }
-
- // Get the native and conversion code sets the
- // server specified in its IOR
- CodeSetComponentInfo serverCodeSets
- = ((CodeSetsComponent)iter.next()).getCodeSetComponentInfo();
-
- // Perform the negotiation between this ORB's code sets and
- // the ones from the IOR
- CodeSetComponentInfo.CodeSetContext result
- = CodeSetConversion.impl().negotiate(
- conn.getBroker().getORBData().getCodeSetComponentInfo(),
- serverCodeSets);
-
- conn.setCodeSetContext(result);
- }
- }
- }
-
- protected void addCodeSetServiceContext(CorbaConnection conn,
- ServiceContexts ctxs,
- GIOPVersion giopVersion) {
-
- // REVISIT. OMG issue 3318 concerning sending the code set
- // service context more than once was deemed too much for the
- // RTF. Here's our strategy for the moment:
- //
- // Send it on every request (necessary in cases of fragmentation
- // with multithreaded clients or when the first thing on a
- // connection is a LocateRequest). Provide an ORB property
- // to disable multiple sends.
- //
- // Note that the connection is null in the local case and no
- // service context is included. We use the ORB provided
- // encapsulation streams.
- //
- // Also, there will be no negotiation or service context
- // in GIOP 1.0. ISO8859-1 is used for char/string, and
- // wchar/wstring are illegal.
- //
- if (giopVersion.equals(GIOPVersion.V1_0) || conn == null)
- return;
-
- CodeSetComponentInfo.CodeSetContext codeSetCtx = null;
-
- if (conn.getBroker().getORBData().alwaysSendCodeSetServiceContext() ||
- !conn.isPostInitialContexts()) {
-
- // Get the negotiated code sets (if any) out of the connection
- codeSetCtx = conn.getCodeSetContext();
- }
-
- // Either we shouldn't send the code set service context, or
- // for some reason, the connection doesn't have its code sets.
- // Perhaps the server didn't include them in the IOR. Uses
- // ISO8859-1 for char and makes wchar/wstring illegal.
- if (codeSetCtx == null)
- return;
-
- CodeSetServiceContext cssc = new CodeSetServiceContext(codeSetCtx);
- ctxs.put(cssc);
- }
-
- protected String peekUserExceptionId(InputObject inputObject)
- {
- CDRInputObject cdrInputObject = (CDRInputObject) inputObject;
- // REVISIT - need interface for mark/reset
- cdrInputObject.mark(Integer.MAX_VALUE);
- String result = cdrInputObject.read_string();
- cdrInputObject.reset();
- return result;
- }
-
- protected void dprint(String msg)
- {
- ORBUtility.dprint("CorbaClientRequestDispatcherImpl", msg);
- }
-
- protected String opAndId(CorbaMessageMediator mediator)
- {
- return ORBUtility.operationNameAndRequestId(mediator);
- }
- }
-
- // End of file.