Save This Page
Home » openjdk-7 » com.sun.corba.se.impl » protocol » [javadoc | source]
    1   /*
    2    * Copyright (c) 2001, 2004, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   
   26   package com.sun.corba.se.impl.protocol;
   27   
   28   import java.io.ByteArrayOutputStream;
   29   import java.io.IOException;
   30   import java.io.PrintWriter;
   31   import java.nio.ByteBuffer;
   32   import java.nio.channels.SelectionKey;
   33   import java.util.EmptyStackException;
   34   import java.util.Iterator;
   35   
   36   import org.omg.CORBA.Any;
   37   import org.omg.CORBA.CompletionStatus;
   38   import org.omg.CORBA.ExceptionList;
   39   import org.omg.CORBA.INTERNAL;
   40   import org.omg.CORBA.Principal;
   41   import org.omg.CORBA.SystemException;
   42   import org.omg.CORBA.TypeCode;
   43   import org.omg.CORBA.UnknownUserException;
   44   import org.omg.CORBA.UNKNOWN;
   45   import org.omg.CORBA.portable.ResponseHandler;
   46   import org.omg.CORBA.portable.UnknownException;
   47   import org.omg.CORBA_2_3.portable.InputStream;
   48   import org.omg.CORBA_2_3.portable.OutputStream;
   49   import org.omg.IOP.ExceptionDetailMessage;
   50   import org.omg.IOP.TAG_RMI_CUSTOM_MAX_STREAM_FORMAT;
   51   
   52   import com.sun.corba.se.pept.broker.Broker;
   53   import com.sun.corba.se.pept.encoding.InputObject;
   54   import com.sun.corba.se.pept.encoding.OutputObject;
   55   import com.sun.corba.se.pept.protocol.MessageMediator;
   56   import com.sun.corba.se.pept.protocol.ProtocolHandler;
   57   import com.sun.corba.se.pept.transport.ByteBufferPool;
   58   import com.sun.corba.se.pept.transport.Connection;
   59   import com.sun.corba.se.pept.transport.ContactInfo;
   60   import com.sun.corba.se.pept.transport.EventHandler;
   61   
   62   import com.sun.corba.se.spi.ior.IOR;
   63   import com.sun.corba.se.spi.ior.ObjectKey;
   64   import com.sun.corba.se.spi.ior.ObjectKeyTemplate;
   65   import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
   66   import com.sun.corba.se.spi.ior.iiop.IIOPProfileTemplate;
   67   import com.sun.corba.se.spi.ior.iiop.IIOPProfile;
   68   import com.sun.corba.se.spi.ior.iiop.MaxStreamFormatVersionComponent;
   69   import com.sun.corba.se.spi.oa.OAInvocationInfo;
   70   import com.sun.corba.se.spi.oa.ObjectAdapter;
   71   import com.sun.corba.se.spi.orb.ORB;
   72   import com.sun.corba.se.spi.orb.ORBVersionFactory;
   73   import com.sun.corba.se.spi.protocol.CorbaMessageMediator;
   74   import com.sun.corba.se.spi.protocol.CorbaProtocolHandler;
   75   import com.sun.corba.se.spi.protocol.CorbaServerRequestDispatcher;
   76   import com.sun.corba.se.spi.protocol.ForwardException;
   77   import com.sun.corba.se.spi.transport.CorbaConnection;
   78   import com.sun.corba.se.spi.transport.CorbaContactInfo;
   79   import com.sun.corba.se.spi.transport.CorbaResponseWaitingRoom;
   80   import com.sun.corba.se.spi.logging.CORBALogDomains;
   81   
   82   import com.sun.corba.se.spi.servicecontext.ORBVersionServiceContext;
   83   import com.sun.corba.se.spi.servicecontext.ServiceContexts;
   84   import com.sun.corba.se.spi.servicecontext.UEInfoServiceContext;
   85   import com.sun.corba.se.spi.servicecontext.MaxStreamFormatVersionServiceContext;
   86   import com.sun.corba.se.spi.servicecontext.SendingContextServiceContext;
   87   import com.sun.corba.se.spi.servicecontext.UnknownServiceContext;
   88   
   89   import com.sun.corba.se.impl.corba.RequestImpl;
   90   import com.sun.corba.se.impl.encoding.BufferManagerFactory;
   91   import com.sun.corba.se.impl.encoding.BufferManagerReadStream;
   92   import com.sun.corba.se.impl.encoding.CDRInputObject;
   93   import com.sun.corba.se.impl.encoding.CDROutputObject;
   94   import com.sun.corba.se.impl.encoding.EncapsOutputStream;
   95   import com.sun.corba.se.impl.logging.ORBUtilSystemException;
   96   import com.sun.corba.se.impl.logging.InterceptorsSystemException;
   97   import com.sun.corba.se.impl.orbutil.ORBConstants;
   98   import com.sun.corba.se.impl.orbutil.ORBUtility;
   99   import com.sun.corba.se.impl.ior.iiop.JavaSerializationComponent;
  100   import com.sun.corba.se.impl.protocol.AddressingDispositionException;
  101   import com.sun.corba.se.impl.protocol.RequestCanceledException;
  102   import com.sun.corba.se.impl.protocol.giopmsgheaders.AddressingDispositionHelper;
  103   import com.sun.corba.se.impl.protocol.giopmsgheaders.CancelRequestMessage;
  104   import com.sun.corba.se.impl.protocol.giopmsgheaders.FragmentMessage_1_1;
  105   import com.sun.corba.se.impl.protocol.giopmsgheaders.FragmentMessage_1_2;
  106   import com.sun.corba.se.impl.protocol.giopmsgheaders.LocateRequestMessage;
  107   import com.sun.corba.se.impl.protocol.giopmsgheaders.LocateRequestMessage_1_0;
  108   import com.sun.corba.se.impl.protocol.giopmsgheaders.LocateRequestMessage_1_1;
  109   import com.sun.corba.se.impl.protocol.giopmsgheaders.LocateRequestMessage_1_2;
  110   import com.sun.corba.se.impl.protocol.giopmsgheaders.LocateReplyOrReplyMessage;
  111   import com.sun.corba.se.impl.protocol.giopmsgheaders.LocateReplyMessage;
  112   import com.sun.corba.se.impl.protocol.giopmsgheaders.LocateReplyMessage_1_0;
  113   import com.sun.corba.se.impl.protocol.giopmsgheaders.LocateReplyMessage_1_1;
  114   import com.sun.corba.se.impl.protocol.giopmsgheaders.LocateReplyMessage_1_2;
  115   import com.sun.corba.se.impl.protocol.giopmsgheaders.Message;
  116   import com.sun.corba.se.impl.protocol.giopmsgheaders.MessageBase;
  117   import com.sun.corba.se.impl.protocol.giopmsgheaders.MessageHandler;
  118   import com.sun.corba.se.impl.protocol.giopmsgheaders.ReplyMessage;
  119   import com.sun.corba.se.impl.protocol.giopmsgheaders.ReplyMessage_1_0;
  120   import com.sun.corba.se.impl.protocol.giopmsgheaders.ReplyMessage_1_1;
  121   import com.sun.corba.se.impl.protocol.giopmsgheaders.ReplyMessage_1_2;
  122   import com.sun.corba.se.impl.protocol.giopmsgheaders.RequestMessage;
  123   import com.sun.corba.se.impl.protocol.giopmsgheaders.RequestMessage_1_0;
  124   import com.sun.corba.se.impl.protocol.giopmsgheaders.RequestMessage_1_1;
  125   import com.sun.corba.se.impl.protocol.giopmsgheaders.RequestMessage_1_2;
  126   
  127   // REVISIT: make sure no memory leaks in client/server request/reply maps.
  128   // REVISIT: normalize requestHeader, replyHeader, messageHeader.
  129   
  130   /**
  131    * @author Harold Carr
  132    */
  133   public class CorbaMessageMediatorImpl
  134       implements
  135           CorbaMessageMediator,
  136           CorbaProtocolHandler,
  137           MessageHandler
  138   {
  139       protected ORB orb;
  140       protected ORBUtilSystemException wrapper ;
  141       protected InterceptorsSystemException interceptorWrapper ;
  142       protected CorbaContactInfo contactInfo;
  143       protected CorbaConnection connection;
  144       protected short addrDisposition;
  145       protected CDROutputObject outputObject;
  146       protected CDRInputObject inputObject;
  147       protected Message messageHeader;
  148       protected RequestMessage requestHeader;
  149       protected LocateReplyOrReplyMessage replyHeader;
  150       protected String replyExceptionDetailMessage;
  151       protected IOR replyIOR;
  152       protected Integer requestIdInteger;
  153       protected Message dispatchHeader;
  154       protected ByteBuffer dispatchByteBuffer;
  155       protected byte streamFormatVersion;
  156       protected boolean streamFormatVersionSet = false;
  157   
  158       protected org.omg.CORBA.Request diiRequest;
  159   
  160       protected boolean cancelRequestAlreadySent = false;
  161   
  162       protected ProtocolHandler protocolHandler;
  163       protected boolean _executeReturnServantInResponseConstructor = false;
  164       protected boolean _executeRemoveThreadInfoInResponseConstructor = false;
  165       protected boolean _executePIInResponseConstructor = false;
  166   
  167       //
  168       // Client-side constructor.
  169       //
  170   
  171       public CorbaMessageMediatorImpl(ORB orb,
  172                                       ContactInfo contactInfo,
  173                                       Connection connection,
  174                                       GIOPVersion giopVersion,
  175                                       IOR ior,
  176                                       int requestId,
  177                                       short addrDisposition,
  178                                       String operationName,
  179                                       boolean isOneWay)
  180       {
  181           this( orb, connection ) ;
  182   
  183           this.contactInfo = (CorbaContactInfo) contactInfo;
  184           this.addrDisposition = addrDisposition;
  185   
  186           streamFormatVersion =
  187               getStreamFormatVersionForThisRequest(
  188                   ((CorbaContactInfo)this.contactInfo).getEffectiveTargetIOR(),
  189                   giopVersion);
  190           streamFormatVersionSet = true;
  191   
  192           requestHeader = (RequestMessage) MessageBase.createRequest(
  193               this.orb,
  194               giopVersion,
  195               ORBUtility.getEncodingVersion(orb, ior),
  196               requestId,
  197               !isOneWay,
  198               ((CorbaContactInfo)this.contactInfo).getEffectiveTargetIOR(),
  199               this.addrDisposition,
  200               operationName,
  201               new ServiceContexts(orb),
  202               null);
  203       }
  204   
  205       //
  206       // Acceptor constructor.
  207       //
  208   
  209       public CorbaMessageMediatorImpl(ORB orb,
  210                                       Connection connection)
  211       {
  212           this.orb = orb;
  213           this.connection = (CorbaConnection)connection;
  214           this.wrapper = ORBUtilSystemException.get( orb,
  215               CORBALogDomains.RPC_PROTOCOL ) ;
  216           this.interceptorWrapper = InterceptorsSystemException.get( orb,
  217               CORBALogDomains.RPC_PROTOCOL ) ;
  218       }
  219   
  220       //
  221       // Dispatcher constructor.
  222       //
  223   
  224       // Note: in some cases (e.g., a reply message) this message
  225       // mediator will only be used for dispatch.  Then the original
  226       // request side mediator will take over.
  227       public CorbaMessageMediatorImpl(ORB orb,
  228                                       CorbaConnection connection,
  229                                       Message dispatchHeader,
  230                                       ByteBuffer byteBuffer)
  231       {
  232           this( orb, connection ) ;
  233           this.dispatchHeader = dispatchHeader;
  234           this.dispatchByteBuffer = byteBuffer;
  235       }
  236   
  237       ////////////////////////////////////////////////////
  238       //
  239       // MessageMediator
  240       //
  241   
  242       public Broker getBroker()
  243       {
  244           return orb;
  245       }
  246   
  247       public ContactInfo getContactInfo()
  248       {
  249           return contactInfo;
  250       }
  251   
  252       public Connection getConnection()
  253       {
  254           return connection;
  255       }
  256   
  257       public void initializeMessage()
  258       {
  259           getRequestHeader().write(outputObject);
  260       }
  261   
  262       public void finishSendingRequest()
  263       {
  264           // REVISIT: probably move logic in outputObject to here.
  265           outputObject.finishSendingMessage();
  266       }
  267   
  268       public InputObject waitForResponse()
  269       {
  270           if (getRequestHeader().isResponseExpected()) {
  271               return connection.waitForResponse(this);
  272           }
  273           return null;
  274       }
  275   
  276       public void setOutputObject(OutputObject outputObject)
  277       {
  278           this.outputObject = (CDROutputObject) outputObject;
  279       }
  280   
  281       public OutputObject getOutputObject()
  282       {
  283           return outputObject;
  284       }
  285   
  286       public void setInputObject(InputObject inputObject)
  287       {
  288           this.inputObject = (CDRInputObject) inputObject;
  289       }
  290   
  291       public InputObject getInputObject()
  292       {
  293           return inputObject;
  294       }
  295   
  296       ////////////////////////////////////////////////////
  297       //
  298       // CorbaMessageMediator
  299       //
  300   
  301       public void setReplyHeader(LocateReplyOrReplyMessage header)
  302       {
  303           this.replyHeader = header;
  304           this.replyIOR = header.getIOR(); // REVISIT - need separate field?
  305       }
  306   
  307       public LocateReplyMessage getLocateReplyHeader()
  308       {
  309           return (LocateReplyMessage) replyHeader;
  310       }
  311   
  312       public ReplyMessage getReplyHeader()
  313       {
  314           return (ReplyMessage) replyHeader;
  315       }
  316   
  317       public void setReplyExceptionDetailMessage(String message)
  318       {
  319           replyExceptionDetailMessage = message;
  320       }
  321   
  322       public RequestMessage getRequestHeader()
  323       {
  324           return requestHeader;
  325       }
  326   
  327       public GIOPVersion getGIOPVersion()
  328       {
  329           if (messageHeader != null) {
  330               return messageHeader.getGIOPVersion();
  331           }
  332           return getRequestHeader().getGIOPVersion();
  333       }
  334   
  335       public byte getEncodingVersion() {
  336           if (messageHeader != null) {
  337               return messageHeader.getEncodingVersion();
  338           }
  339           return getRequestHeader().getEncodingVersion();
  340       }
  341   
  342       public int getRequestId()
  343       {
  344           return getRequestHeader().getRequestId();
  345       }
  346   
  347       public Integer getRequestIdInteger()
  348       {
  349           if (requestIdInteger == null) {
  350               requestIdInteger = new Integer(getRequestHeader().getRequestId());
  351           }
  352           return requestIdInteger;
  353       }
  354   
  355       public boolean isOneWay()
  356       {
  357           return ! getRequestHeader().isResponseExpected();
  358       }
  359   
  360       public short getAddrDisposition()
  361       {
  362           return addrDisposition;
  363       }
  364   
  365       public String getOperationName()
  366       {
  367           return getRequestHeader().getOperation();
  368       }
  369   
  370       public ServiceContexts getRequestServiceContexts()
  371       {
  372           return getRequestHeader().getServiceContexts();
  373       }
  374   
  375       public ServiceContexts getReplyServiceContexts()
  376       {
  377           return getReplyHeader().getServiceContexts();
  378       }
  379   
  380       public void sendCancelRequestIfFinalFragmentNotSent()
  381       {
  382           if ((!sentFullMessage()) && sentFragment() &&
  383               (!cancelRequestAlreadySent))
  384           {
  385               try {
  386                   if (orb.subcontractDebugFlag) {
  387                       dprint(".sendCancelRequestIfFinalFragmentNotSent->: "
  388                              + opAndId(this));
  389                   }
  390                   connection.sendCancelRequestWithLock(getGIOPVersion(),
  391                                                        getRequestId());
  392                   // Case: first a location forward, then a marshaling
  393                   // exception (e.g., non-serializable object).  Only
  394                   // send cancel once.
  395                   cancelRequestAlreadySent = true;
  396               } catch (IOException e) {
  397                   if (orb.subcontractDebugFlag) {
  398                       dprint(".sendCancelRequestIfFinalFragmentNotSent: !ERROR : " + opAndId(this),
  399                              e);
  400                   }
  401   
  402                   // REVISIT: we could attempt to send a final incomplete
  403                   // fragment in this case.
  404                   throw interceptorWrapper.ioexceptionDuringCancelRequest(
  405                       CompletionStatus.COMPLETED_MAYBE, e );
  406               } finally {
  407                   if (orb.subcontractDebugFlag) {
  408                       dprint(".sendCancelRequestIfFinalFragmentNotSent<-: "
  409                              + opAndId(this));
  410                   }
  411               }
  412           }
  413       }
  414   
  415       public boolean sentFullMessage()
  416       {
  417           return outputObject.getBufferManager().sentFullMessage();
  418       }
  419   
  420       public boolean sentFragment()
  421       {
  422           return outputObject.getBufferManager().sentFragment();
  423       }
  424   
  425       public void setDIIInfo(org.omg.CORBA.Request diiRequest)
  426       {
  427           this.diiRequest = diiRequest;
  428       }
  429   
  430       public boolean isDIIRequest()
  431       {
  432           return diiRequest != null;
  433       }
  434   
  435       public Exception unmarshalDIIUserException(String repoId, InputStream is)
  436       {
  437           if (! isDIIRequest()) {
  438               return null;
  439           }
  440   
  441           ExceptionList _exceptions = diiRequest.exceptions();
  442   
  443           try {
  444               // Find the typecode for the exception
  445               for (int i=0; i<_exceptions.count() ; i++) {
  446                   TypeCode tc = _exceptions.item(i);
  447                   if ( tc.id().equals(repoId) ) {
  448                       // Since we dont have the actual user exception
  449                       // class, the spec says we have to create an
  450                       // UnknownUserException and put it in the
  451                       // environment.
  452                       Any eany = orb.create_any();
  453                       eany.read_value(is, (TypeCode)tc);
  454   
  455                       return new UnknownUserException(eany);
  456                   }
  457               }
  458           } catch (Exception b) {
  459               throw wrapper.unexpectedDiiException(b);
  460           }
  461   
  462           // must be a truly unknown exception
  463           return wrapper.unknownCorbaExc( CompletionStatus.COMPLETED_MAYBE);
  464       }
  465   
  466       public void setDIIException(Exception exception)
  467       {
  468           diiRequest.env().exception(exception);
  469       }
  470   
  471       public void handleDIIReply(InputStream inputStream)
  472       {
  473           if (! isDIIRequest()) {
  474               return;
  475           }
  476           ((RequestImpl)diiRequest).unmarshalReply(inputStream);
  477       }
  478   
  479       public Message getDispatchHeader()
  480       {
  481           return dispatchHeader;
  482       }
  483   
  484       public void setDispatchHeader(Message msg)
  485       {
  486           dispatchHeader = msg;
  487       }
  488   
  489       public ByteBuffer getDispatchBuffer()
  490       {
  491           return dispatchByteBuffer;
  492       }
  493   
  494       public void setDispatchBuffer(ByteBuffer byteBuffer)
  495       {
  496           dispatchByteBuffer = byteBuffer;
  497       }
  498   
  499       public int getThreadPoolToUse() {
  500           int poolToUse = 0;
  501           Message msg = getDispatchHeader();
  502           // A null msg should never happen. But, we'll be
  503           // defensive just in case.
  504           if (msg != null) {
  505               poolToUse = msg.getThreadPoolToUse();
  506           }
  507           return poolToUse;
  508       }
  509   
  510       public byte getStreamFormatVersion()
  511       {
  512           // REVISIT: ContactInfo/Acceptor output object factories
  513           // just use this.  Maybe need to distinguish:
  514           //    createOutputObjectForRequest
  515           //    createOutputObjectForReply
  516           // then do getStreamFormatVersionForRequest/ForReply here.
  517           if (streamFormatVersionSet) {
  518               return streamFormatVersion;
  519           }
  520           return getStreamFormatVersionForReply();
  521       }
  522   
  523       /**
  524        * If the RMI-IIOP maximum stream format version service context
  525        * is present, it indicates the maximum stream format version we
  526        * could use for the reply.  If it isn't present, the default is
  527        * 2 for GIOP 1.3 or greater, 1 for lower.
  528        *
  529        * This is only sent on requests.  Clients can find out the
  530        * server's maximum by looking for a tagged component in the IOR.
  531        */
  532       public byte getStreamFormatVersionForReply() {
  533   
  534           // NOTE: The request service contexts may indicate the max.
  535           ServiceContexts svc = getRequestServiceContexts();
  536   
  537           MaxStreamFormatVersionServiceContext msfvsc
  538               = (MaxStreamFormatVersionServiceContext)svc.get(
  539                   MaxStreamFormatVersionServiceContext.SERVICE_CONTEXT_ID);
  540   
  541           if (msfvsc != null) {
  542               byte localMaxVersion = ORBUtility.getMaxStreamFormatVersion();
  543               byte remoteMaxVersion = msfvsc.getMaximumStreamFormatVersion();
  544   
  545               return (byte)Math.min(localMaxVersion, remoteMaxVersion);
  546           } else {
  547               // Defaults to 1 for GIOP 1.2 or less, 2 for
  548               // GIOP 1.3 or higher.
  549               if (getGIOPVersion().lessThan(GIOPVersion.V1_3))
  550                   return ORBConstants.STREAM_FORMAT_VERSION_1;
  551               else
  552                   return ORBConstants.STREAM_FORMAT_VERSION_2;
  553           }
  554       }
  555   
  556       public boolean isSystemExceptionReply()
  557       {
  558           return replyHeader.getReplyStatus() == ReplyMessage.SYSTEM_EXCEPTION;
  559       }
  560   
  561       public boolean isUserExceptionReply()
  562       {
  563           return replyHeader.getReplyStatus() == ReplyMessage.USER_EXCEPTION;
  564       }
  565   
  566       public boolean isLocationForwardReply()
  567       {
  568           return ( (replyHeader.getReplyStatus() == ReplyMessage.LOCATION_FORWARD) ||
  569                    (replyHeader.getReplyStatus() == ReplyMessage.LOCATION_FORWARD_PERM) );
  570           //return replyHeader.getReplyStatus() == ReplyMessage.LOCATION_FORWARD;
  571       }
  572   
  573       public boolean isDifferentAddrDispositionRequestedReply()
  574       {
  575           return replyHeader.getReplyStatus() == ReplyMessage.NEEDS_ADDRESSING_MODE;
  576       }
  577   
  578       public short getAddrDispositionReply()
  579       {
  580           return replyHeader.getAddrDisposition();
  581       }
  582   
  583       public IOR getForwardedIOR()
  584       {
  585           return replyHeader.getIOR();
  586       }
  587   
  588       public SystemException getSystemExceptionReply()
  589       {
  590           return replyHeader.getSystemException(replyExceptionDetailMessage);
  591       }
  592   
  593       ////////////////////////////////////////////////////
  594       //
  595       // Used by server side.
  596       //
  597   
  598       public ObjectKey getObjectKey()
  599       {
  600           return getRequestHeader().getObjectKey();
  601       }
  602   
  603       public void setProtocolHandler(CorbaProtocolHandler protocolHandler)
  604       {
  605           throw wrapper.methodShouldNotBeCalled() ;
  606       }
  607   
  608       public CorbaProtocolHandler getProtocolHandler()
  609       {
  610           // REVISIT: should look up in orb registry.
  611           return this;
  612       }
  613   
  614       ////////////////////////////////////////////////////
  615       //
  616       // ResponseHandler
  617       //
  618   
  619       public org.omg.CORBA.portable.OutputStream createReply()
  620       {
  621           // Note: relies on side-effect of setting mediator output field.
  622           // REVISIT - cast - need interface
  623           getProtocolHandler().createResponse(this, (ServiceContexts) null);
  624           return (OutputStream) getOutputObject();
  625       }
  626   
  627       public org.omg.CORBA.portable.OutputStream createExceptionReply()
  628       {
  629           // Note: relies on side-effect of setting mediator output field.
  630           // REVISIT - cast - need interface
  631           getProtocolHandler().createUserExceptionResponse(this, (ServiceContexts) null);
  632           return (OutputStream) getOutputObject();
  633       }
  634   
  635       public boolean executeReturnServantInResponseConstructor()
  636       {
  637           return _executeReturnServantInResponseConstructor;
  638   
  639       }
  640   
  641       public void setExecuteReturnServantInResponseConstructor(boolean b)
  642       {
  643           _executeReturnServantInResponseConstructor = b;
  644       }
  645   
  646       public boolean executeRemoveThreadInfoInResponseConstructor()
  647       {
  648           return _executeRemoveThreadInfoInResponseConstructor;
  649       }
  650   
  651       public void setExecuteRemoveThreadInfoInResponseConstructor(boolean b)
  652       {
  653           _executeRemoveThreadInfoInResponseConstructor = b;
  654       }
  655   
  656       public boolean executePIInResponseConstructor()
  657       {
  658           return _executePIInResponseConstructor;
  659       }
  660   
  661       public void setExecutePIInResponseConstructor( boolean b )
  662       {
  663           _executePIInResponseConstructor = b;
  664       }
  665   
  666       private byte getStreamFormatVersionForThisRequest(IOR ior,
  667                                                         GIOPVersion giopVersion)
  668       {
  669   
  670           byte localMaxVersion
  671               = ORBUtility.getMaxStreamFormatVersion();
  672   
  673           IOR effectiveTargetIOR =
  674               ((CorbaContactInfo)this.contactInfo).getEffectiveTargetIOR();
  675           IIOPProfileTemplate temp =
  676               (IIOPProfileTemplate)effectiveTargetIOR.getProfile().getTaggedProfileTemplate();
  677           Iterator iter = temp.iteratorById(TAG_RMI_CUSTOM_MAX_STREAM_FORMAT.value);
  678           if (!iter.hasNext()) {
  679               // Didn't have the max stream format version tagged
  680               // component.
  681               if (giopVersion.lessThan(GIOPVersion.V1_3))
  682                   return ORBConstants.STREAM_FORMAT_VERSION_1;
  683               else
  684                   return ORBConstants.STREAM_FORMAT_VERSION_2;
  685           }
  686   
  687           byte remoteMaxVersion
  688               = ((MaxStreamFormatVersionComponent)iter.next()).getMaxStreamFormatVersion();
  689   
  690           return (byte)Math.min(localMaxVersion, remoteMaxVersion);
  691       }
  692   
  693       ////////////////////////////////////////////////////////////////////////
  694       ////////////////////////////////////////////////////////////////////////
  695       ////////////////////////////////////////////////////////////////////////
  696   
  697       // REVISIT - This could be a separate implementation object looked
  698       // up in a registry.  However it needs some state in the message
  699       // mediator so combine for now.
  700   
  701   
  702       protected boolean isThreadDone = false;
  703   
  704       ////////////////////////////////////////////////////
  705       //
  706       // pept.protocol.ProtocolHandler
  707       //
  708   
  709       public boolean handleRequest(MessageMediator messageMediator)
  710       {
  711           try {
  712               dispatchHeader.callback(this);
  713           } catch (IOException e) {
  714               // REVISIT - this should be handled internally.
  715               ;
  716           }
  717           return isThreadDone;
  718       }
  719   
  720       ////////////////////////////////////////////////////
  721       //
  722       // iiop.messages.MessageHandler
  723       //
  724   
  725       private void setWorkThenPoolOrResumeSelect(Message header)
  726       {
  727           if (getConnection().getEventHandler().shouldUseSelectThreadToWait()) {
  728               resumeSelect(header);
  729           } else {
  730               // Leader/Follower when using reader thread.
  731               // When this thread is done working it will go back in pool.
  732   
  733               isThreadDone = true;
  734   
  735               // First unregister current registration.
  736               orb.getTransportManager().getSelector(0)
  737                   .unregisterForEvent(getConnection().getEventHandler());
  738               // Have another thread become the reader.
  739               orb.getTransportManager().getSelector(0)
  740                   .registerForEvent(getConnection().getEventHandler());
  741           }
  742       }
  743   
  744       private void setWorkThenReadOrResumeSelect(Message header)
  745       {
  746           if (getConnection().getEventHandler().shouldUseSelectThreadToWait()) {
  747               resumeSelect(header);
  748           } else {
  749               // When using reader thread then wen this thread is
  750               // done working it will continue reading.
  751               isThreadDone = false;
  752           }
  753       }
  754   
  755       private void resumeSelect(Message header)
  756       {
  757           // NOTE: VERY IMPORTANT:
  758           // Only participate in select after getting to the point
  759           // that proper serialization of fragments is ensured.
  760   
  761           if (transportDebug()) {
  762               dprint(".resumeSelect:->");
  763               // REVISIT: not-OO:
  764               String requestId = "?";
  765               if (header instanceof RequestMessage) {
  766                   requestId =
  767                       new Integer(((RequestMessage)header)
  768                                   .getRequestId()).toString();
  769               } else if (header instanceof ReplyMessage) {
  770                   requestId =
  771                       new Integer(((ReplyMessage)header)
  772                                   .getRequestId()).toString();
  773               } else if (header instanceof FragmentMessage_1_2) {
  774                   requestId =
  775                       new Integer(((FragmentMessage_1_2)header)
  776                                   .getRequestId()).toString();
  777               }
  778               dprint(".resumeSelect: id/"
  779                      + requestId
  780                      + " " + getConnection()
  781                      );
  782   
  783           }
  784   
  785           // IMPORTANT: To avoid bug (4953599), we force the Thread that does the NIO select
  786           // to also do the enable/disable of Ops using SelectionKey.interestOps(Ops of Interest).
  787           // Otherwise, the SelectionKey.interestOps(Ops of Interest) may block indefinitely in
  788           // this thread.
  789           EventHandler eventHandler = getConnection().getEventHandler();
  790           orb.getTransportManager().getSelector(0).registerInterestOps(eventHandler);
  791   
  792           if (transportDebug()) {
  793               dprint(".resumeSelect:<-");
  794           }
  795       }
  796   
  797       private void setInputObject()
  798       {
  799           // REVISIT: refactor createInputObject (and createMessageMediator)
  800           // into base PlugInFactory.  Get via connection (either ContactInfo
  801           // or Acceptor).
  802           if (getConnection().getContactInfo() != null) {
  803               inputObject = (CDRInputObject)
  804                   getConnection().getContactInfo()
  805                   .createInputObject(orb, this);
  806           } else if (getConnection().getAcceptor() != null) {
  807               inputObject = (CDRInputObject)
  808                   getConnection().getAcceptor()
  809                   .createInputObject(orb, this);
  810           } else {
  811               throw new RuntimeException("CorbaMessageMediatorImpl.setInputObject");
  812           }
  813           inputObject.setMessageMediator(this);
  814           setInputObject(inputObject);
  815       }
  816   
  817       private void signalResponseReceived()
  818       {
  819           // This will end up using the MessageMediator associated with
  820           // the original request instead of the current mediator (which
  821           // need to be constructed to hold the dispatchBuffer and connection).
  822           connection.getResponseWaitingRoom()
  823               .responseReceived((InputObject)inputObject);
  824       }
  825   
  826       // This handles message types for which we don't create classes.
  827       public void handleInput(Message header) throws IOException
  828       {
  829           try {
  830               messageHeader = header;
  831   
  832               if (transportDebug())
  833                   dprint(".handleInput->: "
  834                          + MessageBase.typeToString(header.getType()));
  835   
  836               setWorkThenReadOrResumeSelect(header);
  837   
  838               switch(header.getType())
  839               {
  840               case Message.GIOPCloseConnection:
  841                   if (transportDebug()) {
  842                       dprint(".handleInput: CloseConnection: purging");
  843                   }
  844                   connection.purgeCalls(wrapper.connectionRebind(), true, false);
  845                   break;
  846               case Message.GIOPMessageError:
  847                   if (transportDebug()) {
  848                       dprint(".handleInput: MessageError: purging");
  849                   }
  850                   connection.purgeCalls(wrapper.recvMsgError(), true, false);
  851                   break;
  852               default:
  853                   if (transportDebug()) {
  854                       dprint(".handleInput: ERROR: "
  855                              + MessageBase.typeToString(header.getType()));
  856                   }
  857                   throw wrapper.badGiopRequestType() ;
  858               }
  859               releaseByteBufferToPool();
  860           } finally {
  861               if (transportDebug()) {
  862                   dprint(".handleInput<-: "
  863                          + MessageBase.typeToString(header.getType()));
  864               }
  865           }
  866       }
  867   
  868       public void handleInput(RequestMessage_1_0 header) throws IOException
  869       {
  870           try {
  871               if (transportDebug()) dprint(".REQUEST 1.0->: " + header);
  872               try {
  873                   messageHeader = requestHeader = (RequestMessage) header;
  874                   setInputObject();
  875               } finally {
  876                   setWorkThenPoolOrResumeSelect(header);
  877               }
  878               getProtocolHandler().handleRequest(header, this);
  879           } catch (Throwable t) {
  880               if (transportDebug())
  881                   dprint(".REQUEST 1.0: !!ERROR!!: " + header, t);
  882               // Mask the exception from thread.;
  883           } finally {
  884               if (transportDebug()) dprint(".REQUEST 1.0<-: " + header);
  885           }
  886       }
  887   
  888       public void handleInput(RequestMessage_1_1 header) throws IOException
  889       {
  890           try {
  891               if (transportDebug()) dprint(".REQUEST 1.1->: " + header);
  892               try {
  893                   messageHeader = requestHeader = (RequestMessage) header;
  894                   setInputObject();
  895                   connection.serverRequest_1_1_Put(this);
  896               } finally {
  897                   setWorkThenPoolOrResumeSelect(header);
  898               }
  899               getProtocolHandler().handleRequest(header, this);
  900           } catch (Throwable t) {
  901               if (transportDebug())
  902                   dprint(".REQUEST 1.1: !!ERROR!!: " + header, t);
  903               // Mask the exception from thread.;
  904           } finally {
  905               if (transportDebug()) dprint(".REQUEST 1.1<-: " + header);
  906           }
  907       }
  908   
  909       // REVISIT: this is identical to 1_0 except for fragment part.
  910       public void handleInput(RequestMessage_1_2 header) throws IOException
  911       {
  912           try {
  913               try {
  914   
  915                   messageHeader = requestHeader = (RequestMessage) header;
  916   
  917                   header.unmarshalRequestID(dispatchByteBuffer);
  918                   setInputObject();
  919   
  920                   if (transportDebug()) dprint(".REQUEST 1.2->: id/"
  921                                                + header.getRequestId()
  922                                                + ": "
  923                                                + header);
  924   
  925                   // NOTE: in the old code this used to be done conditionally:
  926                   // if (header.moreFragmentsToFollow()).
  927                   // Now we always put it in. We take it out when
  928                   // the response is done.
  929                   // This must happen now so if a header is fragmented the stream
  930                   // may be found.
  931                   connection.serverRequestMapPut(header.getRequestId(), this);
  932               } finally {
  933                   // Leader/Follower.
  934                   // Note: This *MUST* come after putting stream in above map
  935                   // since the header may be fragmented and you do not want to
  936                   // start reading again until the map above is set.
  937                   setWorkThenPoolOrResumeSelect(header);
  938               }
  939               //inputObject.unmarshalHeader(); // done in subcontract.
  940               getProtocolHandler().handleRequest(header, this);
  941           } catch (Throwable t) {
  942               if (transportDebug()) dprint(".REQUEST 1.2: id/"
  943                                            + header.getRequestId()
  944                                            + ": !!ERROR!!: "
  945                                            + header,
  946                                            t);
  947               // Mask the exception from thread.;
  948           } finally {
  949               connection.serverRequestMapRemove(header.getRequestId());
  950   
  951               if (transportDebug()) dprint(".REQUEST 1.2<-: id/"
  952                                            + header.getRequestId()
  953                                            + ": "
  954                                            + header);
  955           }
  956       }
  957   
  958       public void handleInput(ReplyMessage_1_0 header) throws IOException
  959       {
  960           try {
  961               try {
  962                   if (transportDebug()) dprint(".REPLY 1.0->: " + header);
  963                   messageHeader = replyHeader = (ReplyMessage) header;
  964                   setInputObject();
  965   
  966                   // REVISIT: this should be done by waiting thread.
  967                   inputObject.unmarshalHeader();
  968   
  969                   signalResponseReceived();
  970               } finally{
  971                   setWorkThenReadOrResumeSelect(header);
  972               }
  973           } catch (Throwable t) {
  974               if (transportDebug())dprint(".REPLY 1.0: !!ERROR!!: " + header, t);
  975               // Mask the exception from thread.;
  976           } finally {
  977               if (transportDebug()) dprint(".REPLY 1.0<-: " + header);
  978           }
  979       }
  980   
  981       public void handleInput(ReplyMessage_1_1 header) throws IOException
  982       {
  983           try {
  984               if (transportDebug()) dprint(".REPLY 1.1->: " + header);
  985               messageHeader = replyHeader = (ReplyMessage) header;
  986               setInputObject();
  987   
  988               if (header.moreFragmentsToFollow()) {
  989   
  990                   // More fragments are coming to complete this reply, so keep
  991                   // a reference to the InputStream so we can add the fragments
  992                   connection.clientReply_1_1_Put(this);
  993   
  994                   // In 1.1, we can't assume that we have the request ID in the
  995                   // first fragment.  Thus, another thread is used
  996                   // to be the reader while this thread unmarshals
  997                   // the extended header and wakes up the client thread.
  998                   setWorkThenPoolOrResumeSelect(header);
  999   
 1000                   // REVISIT - error handling.
 1001                   // This must be done now.
 1002                   inputObject.unmarshalHeader();
 1003   
 1004                   signalResponseReceived();
 1005   
 1006               } else {
 1007   
 1008                   // Not fragmented, therefore we know the request
 1009                   // ID is here.  Thus, we can unmarshal the extended header
 1010                   // and wake up the client thread without using a third
 1011                   // thread as above.
 1012   
 1013                   // REVISIT - error handling during unmarshal.
 1014                   // This must be done now to get the request id.
 1015                   inputObject.unmarshalHeader();
 1016   
 1017                   signalResponseReceived();
 1018   
 1019                   setWorkThenReadOrResumeSelect(header);
 1020               }
 1021           } catch (Throwable t) {
 1022               if (transportDebug()) dprint(".REPLY 1.1: !!ERROR!!: " + header);
 1023               // Mask the exception from thread.;
 1024           } finally {
 1025               if (transportDebug()) dprint(".REPLY 1.1<-: " + header);
 1026           }
 1027       }
 1028   
 1029       public void handleInput(ReplyMessage_1_2 header) throws IOException
 1030       {
 1031           try {
 1032               try {
 1033                   messageHeader = replyHeader = (ReplyMessage) header;
 1034   
 1035                   // We know that the request ID is in the first fragment
 1036                   header.unmarshalRequestID(dispatchByteBuffer);
 1037   
 1038                   if (transportDebug()) {
 1039                       dprint(".REPLY 1.2->: id/"
 1040                              + + header.getRequestId()
 1041                              + ": more?: " + header.moreFragmentsToFollow()
 1042                              + ": " + header);
 1043                   }
 1044   
 1045                   setInputObject();
 1046   
 1047                   signalResponseReceived();
 1048               } finally {
 1049                   setWorkThenReadOrResumeSelect(header);
 1050               }
 1051           } catch (Throwable t) {
 1052               if (transportDebug()) dprint(".REPLY 1.2: id/"
 1053                                            + header.getRequestId()
 1054                                            + ": !!ERROR!!: "
 1055                                            + header, t);
 1056               // Mask the exception from thread.;
 1057           } finally {
 1058               if (transportDebug()) dprint(".REPLY 1.2<-: id/"
 1059                                            + header.getRequestId()
 1060                                            + ": "
 1061                                            + header);
 1062           }
 1063       }
 1064   
 1065       public void handleInput(LocateRequestMessage_1_0 header) throws IOException
 1066       {
 1067           try {
 1068               if (transportDebug())
 1069                   dprint(".LOCATE_REQUEST 1.0->: " + header);
 1070               try {
 1071                   messageHeader = header;
 1072                   setInputObject();
 1073               } finally {
 1074                   setWorkThenPoolOrResumeSelect(header);
 1075               }
 1076               getProtocolHandler().handleRequest(header, this);
 1077           } catch (Throwable t) {
 1078               if (transportDebug())
 1079                   dprint(".LOCATE_REQUEST 1.0: !!ERROR!!: " + header, t);
 1080               // Mask the exception from thread.;
 1081           } finally {
 1082               if (transportDebug())
 1083                   dprint(".LOCATE_REQUEST 1.0<-: " + header);
 1084           }
 1085   
 1086       }
 1087   
 1088       public void handleInput(LocateRequestMessage_1_1 header) throws IOException
 1089       {
 1090           try {
 1091               if (transportDebug())
 1092                   dprint(".LOCATE_REQUEST 1.1->: " + header);
 1093               try {
 1094                   messageHeader = header;
 1095                   setInputObject();
 1096               } finally {
 1097                   setWorkThenPoolOrResumeSelect(header);
 1098               }
 1099               getProtocolHandler().handleRequest(header, this);
 1100           } catch (Throwable t) {
 1101               if (transportDebug())
 1102                   dprint(".LOCATE_REQUEST 1.1: !!ERROR!!: " + header, t);
 1103               // Mask the exception from thread.;
 1104           } finally {
 1105               if (transportDebug())
 1106                   dprint(".LOCATE_REQUEST 1.1<-:" + header);
 1107           }
 1108       }
 1109   
 1110       public void handleInput(LocateRequestMessage_1_2 header) throws IOException
 1111       {
 1112           try {
 1113               try {
 1114                   messageHeader = header;
 1115   
 1116                   header.unmarshalRequestID(dispatchByteBuffer);
 1117                   setInputObject();
 1118   
 1119                   if (transportDebug())
 1120                       dprint(".LOCATE_REQUEST 1.2->: id/"
 1121                              + header.getRequestId()
 1122                              + ": "
 1123                              + header);
 1124   
 1125                   if (header.moreFragmentsToFollow()) {
 1126                       connection.serverRequestMapPut(header.getRequestId(),this);
 1127                   }
 1128               } finally {
 1129                   setWorkThenPoolOrResumeSelect(header);
 1130               }
 1131               getProtocolHandler().handleRequest(header, this);
 1132           } catch (Throwable t) {
 1133               if (transportDebug())
 1134                   dprint(".LOCATE_REQUEST 1.2: id/"
 1135                          + header.getRequestId()
 1136                          + ": !!ERROR!!: "
 1137                          + header, t);
 1138               // Mask the exception from thread.;
 1139           } finally {
 1140               if (transportDebug())
 1141                   dprint(".LOCATE_REQUEST 1.2<-: id/"
 1142                          + header.getRequestId()
 1143                          + ": "
 1144                          + header);
 1145           }
 1146       }
 1147   
 1148       public void handleInput(LocateReplyMessage_1_0 header) throws IOException
 1149       {
 1150           try {
 1151               if (transportDebug())
 1152                   dprint(".LOCATE_REPLY 1.0->:" + header);
 1153               try {
 1154                   messageHeader = header;
 1155                   setInputObject();
 1156                   inputObject.unmarshalHeader(); // REVISIT Put in subcontract.
 1157                   signalResponseReceived();
 1158               } finally {
 1159                   setWorkThenReadOrResumeSelect(header);
 1160               }
 1161           } catch (Throwable t) {
 1162               if (transportDebug())
 1163                   dprint(".LOCATE_REPLY 1.0: !!ERROR!!: " + header, t);
 1164               // Mask the exception from thread.;
 1165           } finally {
 1166               if (transportDebug())
 1167                   dprint(".LOCATE_REPLY 1.0<-: " + header);
 1168           }
 1169       }
 1170   
 1171       public void handleInput(LocateReplyMessage_1_1 header) throws IOException
 1172       {
 1173           try {
 1174               if (transportDebug()) dprint(".LOCATE_REPLY 1.1->: " + header);
 1175               try {
 1176                   messageHeader = header;
 1177                   setInputObject();
 1178                   // Fragmented LocateReplies are not allowed in 1.1.
 1179                   inputObject.unmarshalHeader();
 1180                   signalResponseReceived();
 1181               } finally {
 1182                   setWorkThenReadOrResumeSelect(header);
 1183               }
 1184           } catch (Throwable t) {
 1185               if (transportDebug())
 1186                   dprint(".LOCATE_REPLY 1.1: !!ERROR!!: " + header, t);
 1187               // Mask the exception from thread.;
 1188           } finally {
 1189               if (transportDebug()) dprint(".LOCATE_REPLY 1.1<-: " + header);
 1190           }
 1191       }
 1192   
 1193       public void handleInput(LocateReplyMessage_1_2 header) throws IOException
 1194       {
 1195           try {
 1196               try {
 1197                   messageHeader = header;
 1198   
 1199                   // No need to put in client reply map - already there.
 1200                   header.unmarshalRequestID(dispatchByteBuffer);
 1201   
 1202                   setInputObject();
 1203   
 1204                   if (transportDebug()) dprint(".LOCATE_REPLY 1.2->: id/"
 1205                                                + header.getRequestId()
 1206                                                + ": "
 1207                                                + header);
 1208   
 1209                   signalResponseReceived();
 1210               } finally {
 1211                   setWorkThenPoolOrResumeSelect(header); // REVISIT
 1212               }
 1213           } catch (Throwable t) {
 1214               if (transportDebug())
 1215                   dprint(".LOCATE_REPLY 1.2: id/"
 1216                          + header.getRequestId()
 1217                          + ": !!ERROR!!: "
 1218                          + header, t);
 1219               // Mask the exception from thread.;
 1220           } finally {
 1221               if (transportDebug()) dprint(".LOCATE_REPLY 1.2<-: id/"
 1222                                            + header.getRequestId()
 1223                                            + ": "
 1224                                            + header);
 1225           }
 1226       }
 1227   
 1228       public void handleInput(FragmentMessage_1_1 header) throws IOException
 1229       {
 1230           try {
 1231               if (transportDebug()) {
 1232                   dprint(".FRAGMENT 1.1->: "
 1233                          + "more?: " + header.moreFragmentsToFollow()
 1234                          + ": " + header);
 1235               }
 1236               try {
 1237                   messageHeader = header;
 1238                   MessageMediator mediator = null;
 1239                   CDRInputObject inputObject = null;
 1240   
 1241                   if (connection.isServer()) {
 1242                       mediator = connection.serverRequest_1_1_Get();
 1243                   } else {
 1244                       mediator = connection.clientReply_1_1_Get();
 1245                   }
 1246                   if (mediator != null) {
 1247                       inputObject = (CDRInputObject) mediator.getInputObject();
 1248                   }
 1249   
 1250                   // If no input stream available, then discard the fragment.
 1251                   // This can happen:
 1252                   // 1. if a fragment message is received prior to receiving
 1253                   //    the original request/reply message. Very unlikely.
 1254                   // 2. if a fragment message is received after the
 1255                   //    reply has been sent (early replies)
 1256                   // Note: In the case of early replies, the fragments received
 1257                   // during the request processing (which are never unmarshaled),
 1258                   // will eventually be discarded by the GC.
 1259                   if (inputObject == null) {
 1260                       if (transportDebug())
 1261                           dprint(".FRAGMENT 1.1: ++++DISCARDING++++: " + header);
 1262                       // need to release dispatchByteBuffer to pool if
 1263                       // we are discarding
 1264                       releaseByteBufferToPool();
 1265                       return;
 1266                   }
 1267   
 1268                   inputObject.getBufferManager()
 1269                       .processFragment(dispatchByteBuffer, header);
 1270   
 1271                   if (! header.moreFragmentsToFollow()) {
 1272                       if (connection.isServer()) {
 1273                           connection.serverRequest_1_1_Remove();
 1274                       } else {
 1275                           connection.clientReply_1_1_Remove();
 1276                       }
 1277                   }
 1278               } finally {
 1279                   // NOTE: This *must* come after queing the fragment
 1280                   // when using the selector to ensure fragments stay in order.
 1281                   setWorkThenReadOrResumeSelect(header);
 1282               }
 1283           } catch (Throwable t) {
 1284               if (transportDebug())
 1285                   dprint(".FRAGMENT 1.1: !!ERROR!!: " + header, t);
 1286               // Mask the exception from thread.;
 1287           } finally {
 1288               if (transportDebug()) dprint(".FRAGMENT 1.1<-: " + header);
 1289           }
 1290       }
 1291   
 1292       public void handleInput(FragmentMessage_1_2 header) throws IOException
 1293       {
 1294           try {
 1295               try {
 1296                   messageHeader = header;
 1297   
 1298                   // Note:  We know it's a 1.2 fragment, we have the data, but
 1299                   // we need the IIOPInputStream instance to unmarshal the
 1300                   // request ID... but we need the request ID to get the
 1301                   // IIOPInputStream instance. So we peek at the raw bytes.
 1302   
 1303                   header.unmarshalRequestID(dispatchByteBuffer);
 1304   
 1305                   if (transportDebug()) {
 1306                       dprint(".FRAGMENT 1.2->: id/"
 1307                              + header.getRequestId()
 1308                              + ": more?: " + header.moreFragmentsToFollow()
 1309                              + ": " + header);
 1310                   }
 1311   
 1312                   MessageMediator mediator = null;
 1313                   InputObject inputObject = null;
 1314   
 1315                   if (connection.isServer()) {
 1316                       mediator =
 1317                           connection.serverRequestMapGet(header.getRequestId());
 1318                   } else {
 1319                       mediator =
 1320                           connection.clientRequestMapGet(header.getRequestId());
 1321                   }
 1322                   if (mediator != null) {
 1323                       inputObject = mediator.getInputObject();
 1324                   }
 1325                   // See 1.1 comments.
 1326                   if (inputObject == null) {
 1327                       if (transportDebug()) {
 1328                           dprint(".FRAGMENT 1.2: id/"
 1329                                  + header.getRequestId()
 1330                                  + ": ++++DISCARDING++++: "
 1331                                  + header);
 1332                       }
 1333                       // need to release dispatchByteBuffer to pool if
 1334                       // we are discarding
 1335                       releaseByteBufferToPool();
 1336                       return;
 1337                   }
 1338                   ((CDRInputObject)inputObject)
 1339                       .getBufferManager().processFragment(
 1340                                        dispatchByteBuffer, header);
 1341   
 1342                   // REVISIT: but if it is a server don't you have to remove the
 1343                   // stream from the map?
 1344                   if (! connection.isServer()) {
 1345                       /* REVISIT
 1346                        * No need to do anything.
 1347                        * Should we mark that last was received?
 1348                        if (! header.moreFragmentsToFollow()) {
 1349                        // Last fragment.
 1350                        }
 1351                       */
 1352                   }
 1353               } finally {
 1354                   // NOTE: This *must* come after queing the fragment
 1355                   // when using the selector to ensure fragments stay in order.
 1356                   setWorkThenReadOrResumeSelect(header);
 1357               }
 1358           } catch (Throwable t) {
 1359               if (transportDebug())
 1360                   dprint(".FRAGMENT 1.2: id/"
 1361                          + header.getRequestId()
 1362                          + ": !!ERROR!!: "
 1363                          + header, t);
 1364               // Mask the exception from thread.;
 1365           } finally {
 1366               if (transportDebug()) dprint(".FRAGMENT 1.2<-: id/"
 1367                                            + header.getRequestId()
 1368                                            + ": "
 1369                                            + header);
 1370           }
 1371       }
 1372   
 1373       public void handleInput(CancelRequestMessage header) throws IOException
 1374       {
 1375           try {
 1376               try {
 1377                   messageHeader = header;
 1378                   setInputObject();
 1379   
 1380                   // REVISIT: Move these two to subcontract.
 1381                   inputObject.unmarshalHeader();
 1382   
 1383                   if (transportDebug()) dprint(".CANCEL->: id/"
 1384                                                + header.getRequestId() + ": "
 1385                                                + header.getGIOPVersion() + ": "
 1386                                                + header);
 1387   
 1388                   processCancelRequest(header.getRequestId());
 1389                   releaseByteBufferToPool();
 1390               } finally {
 1391                   setWorkThenReadOrResumeSelect(header);
 1392               }
 1393           } catch (Throwable t) {
 1394               if (transportDebug()) dprint(".CANCEL: id/"
 1395                                            + header.getRequestId()
 1396                                            + ": !!ERROR!!: "
 1397                                            + header, t);
 1398               // Mask the exception from thread.;
 1399           } finally {
 1400               if (transportDebug()) dprint(".CANCEL<-: id/"
 1401                                            + header.getRequestId() + ": "
 1402                                            + header.getGIOPVersion() + ": "
 1403                                            + header);
 1404           }
 1405       }
 1406   
 1407       private void throwNotImplemented()
 1408       {
 1409           isThreadDone = false;
 1410           throwNotImplemented("");
 1411       }
 1412   
 1413       private void throwNotImplemented(String msg)
 1414       {
 1415           throw new RuntimeException("CorbaMessageMediatorImpl: not implemented " + msg);
 1416       }
 1417   
 1418       private void dprint(String msg, Throwable t)
 1419       {
 1420           dprint(msg);
 1421           t.printStackTrace(System.out);
 1422       }
 1423   
 1424       private void dprint(String msg)
 1425       {
 1426           ORBUtility.dprint("CorbaMessageMediatorImpl", msg);
 1427       }
 1428   
 1429       protected String opAndId(CorbaMessageMediator mediator)
 1430       {
 1431           return ORBUtility.operationNameAndRequestId(mediator);
 1432       }
 1433   
 1434       private boolean transportDebug()
 1435       {
 1436           return orb.transportDebugFlag;
 1437       }
 1438   
 1439       // REVISIT: move this to subcontract (but both client and server need it).
 1440       private final void processCancelRequest(int cancelReqId) {
 1441   
 1442           // The GIOP version of CancelRequest does not matter, since
 1443           // CancelRequest_1_0 could be sent to cancel a request which
 1444           // has a different GIOP version.
 1445   
 1446           /*
 1447            * CancelRequest processing logic :
 1448            *
 1449            *  - find the request with matching requestId
 1450            *
 1451            *  - call cancelProcessing() in BufferManagerRead [BMR]
 1452            *
 1453            *  - the hope is that worker thread would call BMR.underflow()
 1454            *    to wait for more fragments to come in. When BMR.underflow() is
 1455            *    called, if a CancelRequest had already arrived,
 1456            *    the worker thread would throw ThreadDeath,
 1457            *    else the thread would wait to be notified of the
 1458            *    arrival of a new fragment or CancelRequest. Upon notification,
 1459            *    the woken up thread would check to see if a CancelRequest had
 1460            *    arrived and if so throw a ThreadDeath or it will continue to
 1461            *    process the received fragment.
 1462            *
 1463            *  - if all the fragments had been received prior to CancelRequest
 1464            *    then the worker thread would never block in BMR.underflow().
 1465            *    So, setting the abort flag in BMR has no effect. The request
 1466            *    processing will complete normally.
 1467            *
 1468            *  - in the case where the server has received enough fragments to
 1469            *    start processing the request and the server sends out
 1470            *    an early reply. In such a case if the CancelRequest arrives
 1471            *    after the reply has been sent, it has no effect.
 1472            */
 1473   
 1474           if (!connection.isServer()) {
 1475               return; // we do not support bi-directional giop yet, ignore.
 1476           }
 1477   
 1478           // Try to get hold of the InputStream buffer.
 1479           // In the case of 1.0 requests there is no way to get hold of
 1480           // InputStream. Try out the 1.1 and 1.2 cases.
 1481   
 1482           // was the request 1.2 ?
 1483           MessageMediator mediator = connection.serverRequestMapGet(cancelReqId);
 1484           int requestId ;
 1485           if (mediator == null) {
 1486               // was the request 1.1 ?
 1487               mediator = connection.serverRequest_1_1_Get();
 1488               if (mediator == null) {
 1489                   // XXX log this!
 1490                   // either the request was 1.0
 1491                   // or an early reply has already been sent
 1492                   // or request processing is over
 1493                   // or its a spurious CancelRequest
 1494                   return; // do nothing.
 1495               }
 1496   
 1497               requestId = ((CorbaMessageMediator) mediator).getRequestId();
 1498   
 1499               if (requestId != cancelReqId) {
 1500                   // A spurious 1.1 CancelRequest has been received.
 1501                   // XXX log this!
 1502                   return; // do nothing
 1503               }
 1504   
 1505               if (requestId == 0) { // special case
 1506                   // XXX log this
 1507                   // this means that
 1508                   // 1. the 1.1 requests' requestId has not been received
 1509                   //    i.e., a CancelRequest was received even before the
 1510                   //    1.1 request was received. The spec disallows this.
 1511                   // 2. or the 1.1 request has a requestId 0.
 1512                   //
 1513                   // It is a little tricky to distinguish these two. So, be
 1514                   // conservative and do not cancel the request. Downside is that
 1515                   // 1.1 requests with requestId of 0 will never be cancelled.
 1516                   return; // do nothing
 1517               }
 1518           } else {
 1519               requestId = ((CorbaMessageMediator) mediator).getRequestId();
 1520           }
 1521   
 1522           Message msg = ((CorbaMessageMediator)mediator).getRequestHeader();
 1523           if (msg.getType() != Message.GIOPRequest) {
 1524               // Any mediator obtained here should only ever be for a GIOP
 1525               // request.
 1526               wrapper.badMessageTypeForCancel() ;
 1527           }
 1528   
 1529           // At this point we have a valid message mediator that contains
 1530           // a valid requestId.
 1531   
 1532           // at this point we have chosen a request to be cancelled. But we
 1533           // do not know if the target object's method has been invoked or not.
 1534           // Request input stream being available simply means that the request
 1535           // processing is not over yet. simply set the abort flag in the
 1536           // BMRS and hope that the worker thread would notice it (this can
 1537           // happen only if the request stream is being unmarshalled and the
 1538           // target's method has not been invoked yet). This guarantees
 1539           // that the requests which have been dispatched to the
 1540           // target's method will never be cancelled.
 1541   
 1542           BufferManagerReadStream bufferManager = (BufferManagerReadStream)
 1543               ((CDRInputObject)mediator.getInputObject()).getBufferManager();
 1544           bufferManager.cancelProcessing(cancelReqId);
 1545       }
 1546   
 1547       ////////////////////////////////////////////////////
 1548       //
 1549       // spi.protocol.CorbaProtocolHandler
 1550       //
 1551   
 1552       public void handleRequest(RequestMessage msg,
 1553                                 CorbaMessageMediator messageMediator)
 1554       {
 1555           try {
 1556               beginRequest(messageMediator);
 1557               try {
 1558                   handleRequestRequest(messageMediator);
 1559                   if (messageMediator.isOneWay()) {
 1560                       return;
 1561                   }
 1562               } catch (Throwable t) {
 1563                   if (messageMediator.isOneWay()) {
 1564                       return;
 1565                   }
 1566                   handleThrowableDuringServerDispatch(
 1567                       messageMediator, t, CompletionStatus.COMPLETED_MAYBE);
 1568               }
 1569               sendResponse(messageMediator);
 1570           } catch (Throwable t) {
 1571               dispatchError(messageMediator, "RequestMessage", t);
 1572           } finally {
 1573               endRequest(messageMediator);
 1574           }
 1575       }
 1576   
 1577       public void handleRequest(LocateRequestMessage msg,
 1578                                 CorbaMessageMediator messageMediator)
 1579       {
 1580           try {
 1581               beginRequest(messageMediator);
 1582               try {
 1583                   handleLocateRequest(messageMediator);
 1584               } catch (Throwable t) {
 1585                   handleThrowableDuringServerDispatch(
 1586                       messageMediator, t, CompletionStatus.COMPLETED_MAYBE);
 1587               }
 1588               sendResponse(messageMediator);
 1589           } catch (Throwable t) {
 1590               dispatchError(messageMediator, "LocateRequestMessage", t);
 1591           } finally {
 1592               endRequest(messageMediator);
 1593           }
 1594       }
 1595   
 1596       private void beginRequest(CorbaMessageMediator messageMediator)
 1597       {
 1598           ORB orb = (ORB) messageMediator.getBroker();
 1599           if (orb.subcontractDebugFlag) {
 1600               dprint(".handleRequest->:");
 1601           }
 1602           connection.serverRequestProcessingBegins();
 1603       }
 1604   
 1605       private void dispatchError(CorbaMessageMediator messageMediator,
 1606                                  String msg, Throwable t)
 1607       {
 1608           if (orb.subcontractDebugFlag) {
 1609               dprint(".handleRequest: " + opAndId(messageMediator)
 1610                      + ": !!ERROR!!: "
 1611                      + msg,
 1612                      t);
 1613           }
 1614           // REVISIT - this makes hcks sendTwoObjects fail
 1615           // messageMediator.getConnection().close();
 1616       }
 1617   
 1618       private void sendResponse(CorbaMessageMediator messageMediator)
 1619       {
 1620           if (orb.subcontractDebugFlag) {
 1621               dprint(".handleRequest: " + opAndId(messageMediator)
 1622                      + ": sending response");
 1623           }
 1624           // REVISIT - type and location
 1625           CDROutputObject outputObject = (CDROutputObject)
 1626               messageMediator.getOutputObject();
 1627           if (outputObject != null) {
 1628               // REVISIT - can be null for TRANSIENT below.
 1629               outputObject.finishSendingMessage();
 1630           }
 1631       }
 1632   
 1633       private void endRequest(CorbaMessageMediator messageMediator)
 1634       {
 1635           ORB orb = (ORB) messageMediator.getBroker();
 1636           if (orb.subcontractDebugFlag) {
 1637               dprint(".handleRequest<-: " + opAndId(messageMediator));
 1638           }
 1639   
 1640           // release NIO ByteBuffers to ByteBufferPool
 1641   
 1642           try {
 1643               OutputObject outputObj = messageMediator.getOutputObject();
 1644               if (outputObj != null) {
 1645                   outputObj.close();
 1646               }
 1647               InputObject inputObj = messageMediator.getInputObject();
 1648               if (inputObj != null) {
 1649                   inputObj.close();
 1650               }
 1651           } catch (IOException ex) {
 1652               // Given what close() does, this catch shouldn't ever happen.
 1653               // See CDRInput/OutputObject.close() for more info.
 1654               // It also won't result in a Corba error if an IOException happens.
 1655               if (orb.subcontractDebugFlag) {
 1656                   dprint(".endRequest: IOException:" + ex.getMessage(), ex);
 1657               }
 1658           } finally {
 1659               ((CorbaConnection)messageMediator.getConnection()).serverRequestProcessingEnds();
 1660           }
 1661       }
 1662   
 1663       protected void handleRequestRequest(CorbaMessageMediator messageMediator)
 1664       {
 1665           // Does nothing if already unmarshaled.
 1666           ((CDRInputObject)messageMediator.getInputObject()).unmarshalHeader();
 1667   
 1668           ORB orb = (ORB)messageMediator.getBroker();
 1669           orb.checkShutdownState();
 1670   
 1671           ObjectKey okey = messageMediator.getObjectKey();
 1672           if (orb.subcontractDebugFlag) {
 1673               ObjectKeyTemplate oktemp = okey.getTemplate() ;
 1674               dprint( ".handleRequest: " + opAndId(messageMediator)
 1675                       + ": dispatching to scid: " + oktemp.getSubcontractId());
 1676           }
 1677   
 1678           CorbaServerRequestDispatcher sc = okey.getServerRequestDispatcher(orb);
 1679   
 1680           if (orb.subcontractDebugFlag) {
 1681               dprint(".handleRequest: " + opAndId(messageMediator)
 1682                      + ": dispatching to sc: " + sc);
 1683           }
 1684   
 1685           if (sc == null) {
 1686               throw wrapper.noServerScInDispatch() ;
 1687           }
 1688   
 1689           // NOTE:
 1690           // This is necessary so mediator can act as ResponseHandler
 1691           // and pass necessary info to response constructors located
 1692           // in the subcontract.
 1693           // REVISIT - same class right now.
 1694           //messageMediator.setProtocolHandler(this);
 1695   
 1696           try {
 1697               orb.startingDispatch();
 1698               sc.dispatch(messageMediator);
 1699           } finally {
 1700               orb.finishedDispatch();
 1701           }
 1702       }
 1703   
 1704       protected void handleLocateRequest(CorbaMessageMediator messageMediator)
 1705       {
 1706           ORB orb = (ORB)messageMediator.getBroker();
 1707           LocateRequestMessage msg = (LocateRequestMessage)
 1708               messageMediator.getDispatchHeader();
 1709           IOR ior = null;
 1710           LocateReplyMessage reply = null;
 1711           short addrDisp = -1;
 1712   
 1713           try {
 1714               ((CDRInputObject)messageMediator.getInputObject()).unmarshalHeader();
 1715               CorbaServerRequestDispatcher sc =
 1716                   msg.getObjectKey().getServerRequestDispatcher( orb ) ;
 1717               if (sc == null) {
 1718                   return;
 1719               }
 1720   
 1721               ior = sc.locate(msg.getObjectKey());
 1722   
 1723               if ( ior == null ) {
 1724                   reply = MessageBase.createLocateReply(
 1725                               orb, msg.getGIOPVersion(),
 1726                               msg.getEncodingVersion(),
 1727                               msg.getRequestId(),
 1728                               LocateReplyMessage.OBJECT_HERE, null);
 1729   
 1730               } else {
 1731                   reply = MessageBase.createLocateReply(
 1732                               orb, msg.getGIOPVersion(),
 1733                               msg.getEncodingVersion(),
 1734                               msg.getRequestId(),
 1735                               LocateReplyMessage.OBJECT_FORWARD, ior);
 1736               }
 1737               // REVISIT: Should we catch SystemExceptions?
 1738   
 1739           } catch (AddressingDispositionException ex) {
 1740   
 1741               // create a response containing the expected target
 1742               // addressing disposition.
 1743   
 1744               reply = MessageBase.createLocateReply(
 1745                           orb, msg.getGIOPVersion(),
 1746                           msg.getEncodingVersion(),
 1747                           msg.getRequestId(),
 1748                           LocateReplyMessage.LOC_NEEDS_ADDRESSING_MODE, null);
 1749   
 1750               addrDisp = ex.expectedAddrDisp();
 1751   
 1752           } catch (RequestCanceledException ex) {
 1753   
 1754               return; // no need to send reply
 1755   
 1756           } catch ( Exception ex ) {
 1757   
 1758               // REVISIT If exception is not OBJECT_NOT_EXIST, it should
 1759               // have a different reply
 1760   
 1761               // This handles OBJECT_NOT_EXIST exceptions thrown in
 1762               // the subcontract or obj manager. Send back UNKNOWN_OBJECT.
 1763   
 1764               reply = MessageBase.createLocateReply(
 1765                           orb, msg.getGIOPVersion(),
 1766                           msg.getEncodingVersion(),
 1767                           msg.getRequestId(),
 1768                           LocateReplyMessage.UNKNOWN_OBJECT, null);
 1769           }
 1770   
 1771           CDROutputObject outputObject =
 1772               createAppropriateOutputObject(messageMediator,
 1773                                             msg, reply);
 1774           messageMediator.setOutputObject(outputObject);
 1775           outputObject.setMessageMediator(messageMediator);
 1776   
 1777           reply.write(outputObject);
 1778           // outputObject.setMessage(reply); // REVISIT - not necessary
 1779           if (ior != null) {
 1780               ior.write(outputObject);
 1781           }
 1782           if (addrDisp != -1) {
 1783               AddressingDispositionHelper.write(outputObject, addrDisp);
 1784           }
 1785       }
 1786   
 1787       private CDROutputObject createAppropriateOutputObject(
 1788           CorbaMessageMediator messageMediator,
 1789           Message msg, LocateReplyMessage reply)
 1790       {
 1791           CDROutputObject outputObject;
 1792   
 1793           if (msg.getGIOPVersion().lessThan(GIOPVersion.V1_2)) {
 1794               // locate msgs 1.0 & 1.1 :=> grow,
 1795               // REVISIT - build from factory
 1796               outputObject = new CDROutputObject(
 1797                                (ORB) messageMediator.getBroker(),
 1798                                this,
 1799                                GIOPVersion.V1_0,
 1800                                (CorbaConnection) messageMediator.getConnection(),
 1801                                reply,
 1802                                ORBConstants.STREAM_FORMAT_VERSION_1);
 1803           } else {
 1804               // 1.2 :=> stream
 1805               // REVISIT - build from factory
 1806               outputObject = new CDROutputObject(
 1807                                (ORB) messageMediator.getBroker(),
 1808                                messageMediator,
 1809                                reply,
 1810                                ORBConstants.STREAM_FORMAT_VERSION_1);
 1811           }
 1812           return outputObject;
 1813       }
 1814   
 1815       public void handleThrowableDuringServerDispatch(
 1816           CorbaMessageMediator messageMediator,
 1817           Throwable throwable,
 1818           CompletionStatus completionStatus)
 1819       {
 1820           if (((ORB)messageMediator.getBroker()).subcontractDebugFlag) {
 1821               dprint(".handleThrowableDuringServerDispatch: "
 1822                      + opAndId(messageMediator) + ": "
 1823                      + throwable);
 1824           }
 1825   
 1826           // If we haven't unmarshaled the header, we probably don't
 1827           // have enough information to even send back a reply.
 1828   
 1829           // REVISIT
 1830           // Cannot do this check.  When target addressing disposition does
 1831           // not match (during header unmarshaling) it throws an exception
 1832           // to be handled here.
 1833           /*
 1834           if (! ((CDRInputObject)messageMediator.getInputObject())
 1835               .unmarshaledHeader()) {
 1836               return;
 1837           }
 1838           */
 1839           handleThrowableDuringServerDispatch(messageMediator,
 1840                                               throwable,
 1841                                               completionStatus,
 1842                                               1);
 1843       }
 1844   
 1845   
 1846       // REVISIT - catch and ignore RequestCanceledException.
 1847   
 1848       protected void handleThrowableDuringServerDispatch(
 1849           CorbaMessageMediator messageMediator,
 1850           Throwable throwable,
 1851           CompletionStatus completionStatus,
 1852           int iteration)
 1853       {
 1854           if (iteration > 10) {
 1855               if (((ORB)messageMediator.getBroker()).subcontractDebugFlag) {
 1856                   dprint(".handleThrowableDuringServerDispatch: "
 1857                          + opAndId(messageMediator)
 1858                          + ": cannot handle: "
 1859                          + throwable);
 1860               }
 1861   
 1862               // REVISIT - should we close connection?
 1863               RuntimeException rte =
 1864                   new RuntimeException("handleThrowableDuringServerDispatch: " +
 1865                                        "cannot create response.");
 1866               rte.initCause(throwable);
 1867               throw rte;
 1868           }
 1869   
 1870           try {
 1871               if (throwable instanceof ForwardException) {
 1872                   ForwardException fex = (ForwardException)throwable ;
 1873                   createLocationForward( messageMediator, fex.getIOR(), null ) ;
 1874                   return;
 1875               }
 1876   
 1877               if (throwable instanceof AddressingDispositionException) {
 1878                   handleAddressingDisposition(
 1879                       messageMediator,
 1880                       (AddressingDispositionException)throwable);
 1881                   return;
 1882               }
 1883   
 1884               // Else.
 1885   
 1886               SystemException sex =
 1887                   convertThrowableToSystemException(throwable, completionStatus);
 1888   
 1889               createSystemExceptionResponse(messageMediator, sex, null);
 1890               return;
 1891   
 1892           } catch (Throwable throwable2) {
 1893   
 1894               // User code (e.g., postinvoke, interceptors) may change
 1895               // the exception, so we end up back here.
 1896               // Report the changed exception.
 1897   
 1898               handleThrowableDuringServerDispatch(messageMediator,
 1899                                                   throwable2,
 1900                                                   completionStatus,
 1901                                                   iteration + 1);
 1902               return;
 1903           }
 1904       }
 1905   
 1906       protected SystemException convertThrowableToSystemException(
 1907           Throwable throwable,
 1908           CompletionStatus completionStatus)
 1909       {
 1910           if (throwable instanceof SystemException) {
 1911               return (SystemException)throwable;
 1912           }
 1913   
 1914           if (throwable instanceof RequestCanceledException) {
 1915               // Reporting an exception response causes the
 1916               // poa current stack, the interceptor stacks, etc.
 1917               // to be balanced.  It also notifies interceptors
 1918               // that the request was cancelled.
 1919   
 1920               return wrapper.requestCanceled( throwable ) ;
 1921           }
 1922   
 1923           // NOTE: We do not trap ThreadDeath above Throwable.
 1924           // There is no reason to stop the thread.  It is
 1925           // just a worker thread.  The ORB never throws
 1926           // ThreadDeath.  Client code may (e.g., in ServantManagers,
 1927           // interceptors, or servants) but that should not
 1928           // effect the ORB threads.  So it is just handled
 1929           // generically.
 1930   
 1931           //
 1932           // Last resort.
 1933           // If user code throws a non-SystemException report it generically.
 1934           //
 1935   
 1936           return wrapper.runtimeexception( CompletionStatus.COMPLETED_MAYBE, throwable ) ;
 1937       }
 1938   
 1939       protected void handleAddressingDisposition(
 1940           CorbaMessageMediator messageMediator,
 1941           AddressingDispositionException ex)
 1942       {
 1943   
 1944           short addrDisp = -1;
 1945   
 1946           // from iiop.RequestProcessor.
 1947   
 1948           // Respond with expected target addressing disposition.
 1949   
 1950           switch (messageMediator.getRequestHeader().getType()) {
 1951           case Message.GIOPRequest :
 1952               ReplyMessage replyHeader = MessageBase.createReply(
 1953                             (ORB)messageMediator.getBroker(),
 1954                             messageMediator.getGIOPVersion(),
 1955                             messageMediator.getEncodingVersion(),
 1956                             messageMediator.getRequestId(),
 1957                             ReplyMessage.NEEDS_ADDRESSING_MODE,
 1958                             null, null);
 1959               // REVISIT: via acceptor factory.
 1960               CDROutputObject outputObject = new CDROutputObject(
 1961                   (ORB)messageMediator.getBroker(),
 1962                   this,
 1963                   messageMediator.getGIOPVersion(),
 1964                   (CorbaConnection)messageMediator.getConnection(),
 1965                   replyHeader,
 1966                   ORBConstants.STREAM_FORMAT_VERSION_1);
 1967               messageMediator.setOutputObject(outputObject);
 1968               outputObject.setMessageMediator(messageMediator);
 1969               replyHeader.write(outputObject);
 1970               AddressingDispositionHelper.write(outputObject,
 1971                                                 ex.expectedAddrDisp());
 1972               return;
 1973   
 1974           case Message.GIOPLocateRequest :
 1975               LocateReplyMessage locateReplyHeader = MessageBase.createLocateReply(
 1976                   (ORB)messageMediator.getBroker(),
 1977                   messageMediator.getGIOPVersion(),
 1978                   messageMediator.getEncodingVersion(),
 1979                   messageMediator.getRequestId(),
 1980                   LocateReplyMessage.LOC_NEEDS_ADDRESSING_MODE,
 1981                   null);
 1982   
 1983               addrDisp = ex.expectedAddrDisp();
 1984   
 1985               // REVISIT: via acceptor factory.
 1986               outputObject =
 1987                   createAppropriateOutputObject(messageMediator,
 1988                                                 messageMediator.getRequestHeader(),
 1989                                                 locateReplyHeader);
 1990               messageMediator.setOutputObject(outputObject);
 1991               outputObject.setMessageMediator(messageMediator);
 1992               locateReplyHeader.write(outputObject);
 1993               IOR ior = null;
 1994               if (ior != null) {
 1995                   ior.write(outputObject);
 1996               }
 1997               if (addrDisp != -1) {
 1998                   AddressingDispositionHelper.write(outputObject, addrDisp);
 1999               }
 2000               return;
 2001           }
 2002       }
 2003   
 2004       public CorbaMessageMediator createResponse(
 2005           CorbaMessageMediator messageMediator,
 2006           ServiceContexts svc)
 2007       {
 2008           // REVISIT: ignore service contexts during framework transition.
 2009           // They are set in SubcontractResponseHandler to the wrong connection.
 2010           // Then they would be set again here and a duplicate contexts
 2011           // exception occurs.
 2012           return createResponseHelper(
 2013               messageMediator,
 2014               getServiceContextsForReply(messageMediator, null));
 2015       }
 2016   
 2017       public CorbaMessageMediator createUserExceptionResponse(
 2018           CorbaMessageMediator messageMediator, ServiceContexts svc)
 2019       {
 2020           // REVISIT - same as above
 2021           return createResponseHelper(
 2022               messageMediator,
 2023               getServiceContextsForReply(messageMediator, null),
 2024               true);
 2025       }
 2026   
 2027       public CorbaMessageMediator createUnknownExceptionResponse(
 2028           CorbaMessageMediator messageMediator, UnknownException ex)
 2029       {
 2030           // NOTE: This service context container gets augmented in
 2031           // tail call.
 2032           ServiceContexts contexts = null;
 2033           SystemException sys = new UNKNOWN( 0,
 2034               CompletionStatus.COMPLETED_MAYBE);
 2035           contexts = new ServiceContexts( (ORB)messageMediator.getBroker() );
 2036           UEInfoServiceContext uei = new UEInfoServiceContext(sys);
 2037           contexts.put( uei ) ;
 2038           return createSystemExceptionResponse(messageMediator, sys, contexts);
 2039       }
 2040   
 2041       public CorbaMessageMediator createSystemExceptionResponse(
 2042           CorbaMessageMediator messageMediator,
 2043           SystemException ex,
 2044           ServiceContexts svc)
 2045       {
 2046           if (messageMediator.getConnection() != null) {
 2047               // It is possible that fragments of response have already been
 2048               // sent.  Then an error may occur (e.g. marshaling error like
 2049               // non serializable object).  In that case it is too late
 2050               // to send the exception.  We just return the existing fragmented
 2051               // stream here.  This will cause an incomplete last fragment
 2052               // to be sent.  Then the other side will get a marshaling error
 2053               // when attempting to unmarshal.
 2054   
 2055               // REVISIT: Impl - make interface method to do the following.
 2056               CorbaMessageMediatorImpl mediator = (CorbaMessageMediatorImpl)
 2057                   ((CorbaConnection)messageMediator.getConnection())
 2058                   .serverRequestMapGet(messageMediator.getRequestId());
 2059   
 2060               OutputObject existingOutputObject = null;
 2061               if (mediator != null) {
 2062                   existingOutputObject = mediator.getOutputObject();
 2063               }
 2064   
 2065               // REVISIT: need to think about messageMediator containing correct
 2066               // pointer to output object.
 2067               if (existingOutputObject != null &&
 2068                   mediator.sentFragment() &&
 2069                   ! mediator.sentFullMessage())
 2070               {
 2071                   return mediator;
 2072               }
 2073           }
 2074   
 2075           // Only do this if interceptors have been initialized on this request
 2076           // and have not completed their lifecycle (otherwise the info stack
 2077           // may be empty or have a different request's entry on top).
 2078           if (messageMediator.executePIInResponseConstructor()) {
 2079               // REVISIT: not necessary in framework now?
 2080               // Inform Portable Interceptors of the SystemException.  This is
 2081               // required to be done here because the ending interception point
 2082               // is called in the when creating the response below
 2083               // but we do not currently write the SystemException into the
 2084               // response until after the ending point is called.
 2085               ((ORB)messageMediator.getBroker()).getPIHandler().setServerPIInfo( ex );
 2086           }
 2087   
 2088           if (((ORB)messageMediator.getBroker()).subcontractDebugFlag &&
 2089               ex != null)
 2090           {
 2091               dprint(".createSystemExceptionResponse: "
 2092                      + opAndId(messageMediator),
 2093                      ex);
 2094           }
 2095   
 2096           ServiceContexts serviceContexts =
 2097               getServiceContextsForReply(messageMediator, svc);
 2098   
 2099           // NOTE: We MUST add the service context before creating
 2100           // the response since service contexts are written to the
 2101           // stream when the response object is created.
 2102   
 2103           addExceptionDetailMessage(messageMediator, ex, serviceContexts);
 2104   
 2105           CorbaMessageMediator response =
 2106               createResponseHelper(messageMediator, serviceContexts, false);
 2107   
 2108           // NOTE: From here on, it is too late to add more service contexts.
 2109           // They have already been serialized to the stream (and maybe fragments
 2110           // sent).
 2111   
 2112           ORBUtility.writeSystemException(
 2113               ex, (OutputStream)response.getOutputObject());
 2114   
 2115           return response;
 2116       }
 2117   
 2118       private void addExceptionDetailMessage(CorbaMessageMediator mediator,
 2119                                              SystemException ex,
 2120                                              ServiceContexts serviceContexts)
 2121       {
 2122           ByteArrayOutputStream baos = new ByteArrayOutputStream();
 2123           PrintWriter pw = new PrintWriter(baos);
 2124           ex.printStackTrace(pw);
 2125           pw.flush(); // NOTE: you must flush or baos will be empty.
 2126           EncapsOutputStream encapsOutputStream =
 2127               new EncapsOutputStream((ORB)mediator.getBroker());
 2128           encapsOutputStream.putEndian();
 2129           encapsOutputStream.write_wstring(baos.toString());
 2130           UnknownServiceContext serviceContext =
 2131               new UnknownServiceContext(ExceptionDetailMessage.value,
 2132                                         encapsOutputStream.toByteArray());
 2133           serviceContexts.put(serviceContext);
 2134       }
 2135   
 2136       public CorbaMessageMediator createLocationForward(
 2137           CorbaMessageMediator messageMediator, IOR ior, ServiceContexts svc)
 2138       {
 2139           ReplyMessage reply
 2140               = MessageBase.createReply(
 2141                     (ORB)messageMediator.getBroker(),
 2142                     messageMediator.getGIOPVersion(),
 2143                     messageMediator.getEncodingVersion(),
 2144                     messageMediator.getRequestId(),
 2145                     ReplyMessage.LOCATION_FORWARD,
 2146                     getServiceContextsForReply(messageMediator, svc),
 2147                     ior);
 2148   
 2149           return createResponseHelper(messageMediator, reply, ior);
 2150       }
 2151   
 2152       protected CorbaMessageMediator createResponseHelper(
 2153           CorbaMessageMediator messageMediator, ServiceContexts svc)
 2154       {
 2155           ReplyMessage message =
 2156               MessageBase.createReply(
 2157                   (ORB)messageMediator.getBroker(),
 2158                   messageMediator.getGIOPVersion(),
 2159                   messageMediator.getEncodingVersion(),
 2160                   messageMediator.getRequestId(),
 2161                   ReplyMessage.NO_EXCEPTION,
 2162                   svc,
 2163                   null);
 2164           return createResponseHelper(messageMediator, message, null);
 2165       }
 2166   
 2167       protected CorbaMessageMediator createResponseHelper(
 2168           CorbaMessageMediator messageMediator, ServiceContexts svc,boolean user)
 2169       {
 2170           ReplyMessage message =
 2171               MessageBase.createReply(
 2172                   (ORB)messageMediator.getBroker(),
 2173                   messageMediator.getGIOPVersion(),
 2174                   messageMediator.getEncodingVersion(),
 2175                   messageMediator.getRequestId(),
 2176                   user ? ReplyMessage.USER_EXCEPTION :
 2177                          ReplyMessage.SYSTEM_EXCEPTION,
 2178                   svc,
 2179                   null);
 2180           return createResponseHelper(messageMediator, message, null);
 2181       }
 2182   
 2183       // REVISIT - IOR arg is ignored.
 2184       protected CorbaMessageMediator createResponseHelper(
 2185           CorbaMessageMediator messageMediator, ReplyMessage reply, IOR ior)
 2186       {
 2187           // REVISIT - these should be invoked from subcontract.
 2188           runServantPostInvoke(messageMediator);
 2189           runInterceptors(messageMediator, reply);
 2190           runRemoveThreadInfo(messageMediator);
 2191   
 2192           if (((ORB)messageMediator.getBroker()).subcontractDebugFlag) {
 2193               dprint(".createResponseHelper: "
 2194                      + opAndId(messageMediator) + ": "
 2195                      + reply);
 2196           }
 2197   
 2198           messageMediator.setReplyHeader(reply);
 2199   
 2200           OutputObject replyOutputObject;
 2201           // REVISIT = do not use null.
 2202           //
 2203           if (messageMediator.getConnection() == null) {
 2204               // REVISIT - needs factory
 2205               replyOutputObject =
 2206                   new CDROutputObject(orb, messageMediator,
 2207                                       messageMediator.getReplyHeader(),
 2208                                       messageMediator.getStreamFormatVersion(),
 2209                                       BufferManagerFactory.GROW);
 2210           } else {
 2211               replyOutputObject = messageMediator.getConnection().getAcceptor()
 2212                .createOutputObject(messageMediator.getBroker(), messageMediator);
 2213           }
 2214           messageMediator.setOutputObject(replyOutputObject);
 2215           messageMediator.getOutputObject().setMessageMediator(messageMediator);
 2216   
 2217           reply.write((OutputStream) messageMediator.getOutputObject());
 2218           if (reply.getIOR() != null) {
 2219               reply.getIOR().write((OutputStream) messageMediator.getOutputObject());
 2220           }
 2221           // REVISIT - not necessary?
 2222           //messageMediator.this.replyIOR = reply.getIOR();
 2223   
 2224           // NOTE: The mediator holds onto output object so return value
 2225           // not really necessary.
 2226           return messageMediator;
 2227       }
 2228   
 2229       protected void runServantPostInvoke(CorbaMessageMediator messageMediator)
 2230       {
 2231           // Run ServantLocator::postinvoke.  This may cause a SystemException
 2232           // which will throw out of the constructor and return later
 2233           // to construct a reply for that exception.  The internal logic
 2234           // of returnServant makes sure that postinvoke is only called once.
 2235           // REVISIT: instead of instanceof, put method on all orbs.
 2236           ORB orb = null;
 2237           // This flag is to deal with BootstrapServer use of reply streams,
 2238           // with ServerRequestDispatcher's use of reply streams, etc.
 2239           if (messageMediator.executeReturnServantInResponseConstructor()) {
 2240               // It is possible to get marshaling errors in the skeleton after
 2241               // postinvoke has completed.  We must set this to false so that
 2242               // when the error exception reply is constructed we don't try
 2243               // to incorrectly access poa current (which will be the wrong
 2244               // one or an empty stack.
 2245               messageMediator.setExecuteReturnServantInResponseConstructor(false);
 2246               messageMediator.setExecuteRemoveThreadInfoInResponseConstructor(true);
 2247   
 2248               try {
 2249                   orb = (ORB)messageMediator.getBroker();
 2250                   OAInvocationInfo info = orb.peekInvocationInfo() ;
 2251                   ObjectAdapter oa = info.oa();
 2252                   try {
 2253                       oa.returnServant() ;
 2254                   } catch (Throwable thr) {
 2255                       wrapper.unexpectedException( thr ) ;
 2256   
 2257                       if (thr instanceof Error)
 2258                           throw (Error)thr ;
 2259                       else if (thr instanceof RuntimeException)
 2260                           throw (RuntimeException)thr ;
 2261                   } finally {
 2262                       oa.exit();
 2263                   }
 2264               } catch (EmptyStackException ese) {
 2265                   throw wrapper.emptyStackRunServantPostInvoke( ese ) ;
 2266               }
 2267           }
 2268       }
 2269   
 2270       protected void runInterceptors(CorbaMessageMediator messageMediator,
 2271                                      ReplyMessage reply)
 2272       {
 2273           if( messageMediator.executePIInResponseConstructor() ) {
 2274               // Invoke server request ending interception points (send_*):
 2275               // Note: this may end up with a SystemException or an internal
 2276               // Runtime ForwardRequest
 2277               ((ORB)messageMediator.getBroker()).getPIHandler().
 2278                   invokeServerPIEndingPoint( reply );
 2279   
 2280               // Note this will be executed even if a ForwardRequest or
 2281               // SystemException is thrown by a Portable Interceptors ending
 2282               // point since we end up in this constructor again anyway.
 2283               ((ORB)messageMediator.getBroker()).getPIHandler().
 2284                   cleanupServerPIRequest();
 2285   
 2286               // See createSystemExceptionResponse for why this is necesary.
 2287               messageMediator.setExecutePIInResponseConstructor(false);
 2288           }
 2289       }
 2290   
 2291       protected void runRemoveThreadInfo(CorbaMessageMediator messageMediator)
 2292       {
 2293           // Once you get here then the final reply is available (i.e.,
 2294           // postinvoke and interceptors have completed.
 2295           if (messageMediator.executeRemoveThreadInfoInResponseConstructor()) {
 2296               messageMediator.setExecuteRemoveThreadInfoInResponseConstructor(false);
 2297               ((ORB)messageMediator.getBroker()).popInvocationInfo() ;
 2298           }
 2299       }
 2300   
 2301       protected ServiceContexts getServiceContextsForReply(
 2302           CorbaMessageMediator messageMediator, ServiceContexts contexts)
 2303       {
 2304           CorbaConnection c = (CorbaConnection) messageMediator.getConnection();
 2305   
 2306           if (((ORB)messageMediator.getBroker()).subcontractDebugFlag) {
 2307               dprint(".getServiceContextsForReply: "
 2308                      + opAndId(messageMediator)
 2309                      + ": " + c);
 2310           }
 2311   
 2312           if (contexts == null) {
 2313               contexts = new ServiceContexts(((ORB)messageMediator.getBroker()));
 2314           }
 2315   
 2316           // NOTE : We only want to send the runtime context the first time
 2317   
 2318           if (c != null && !c.isPostInitialContexts()) {
 2319               c.setPostInitialContexts();
 2320               SendingContextServiceContext scsc =
 2321                   new SendingContextServiceContext(
 2322                       ((ORB)messageMediator.getBroker()).getFVDCodeBaseIOR()) ;
 2323   
 2324               if (contexts.get( scsc.getId() ) != null)
 2325                   throw wrapper.duplicateSendingContextServiceContext() ;
 2326   
 2327               contexts.put( scsc ) ;
 2328   
 2329               if ( ((ORB)messageMediator.getBroker()).subcontractDebugFlag)
 2330                   dprint(".getServiceContextsForReply: "
 2331                          + opAndId(messageMediator)
 2332                          + ": added SendingContextServiceContext" ) ;
 2333           }
 2334   
 2335           // send ORBVersion servicecontext as part of the Reply
 2336   
 2337           ORBVersionServiceContext ovsc
 2338               = new ORBVersionServiceContext(ORBVersionFactory.getORBVersion());
 2339   
 2340           if (contexts.get( ovsc.getId() ) != null)
 2341               throw wrapper.duplicateOrbVersionServiceContext() ;
 2342   
 2343           contexts.put( ovsc ) ;
 2344   
 2345           if ( ((ORB)messageMediator.getBroker()).subcontractDebugFlag)
 2346               dprint(".getServiceContextsForReply: "
 2347                      + opAndId(messageMediator)
 2348                      + ": added ORB version service context");
 2349   
 2350           return contexts;
 2351       }
 2352   
 2353       // REVISIT - this method should be migrated to orbutil.ORBUtility
 2354       //           since all locations that release ByteBuffers use
 2355       //           very similar logic and debug information.
 2356       private void releaseByteBufferToPool() {
 2357           if (dispatchByteBuffer != null) {
 2358               orb.getByteBufferPool().releaseByteBuffer(dispatchByteBuffer);
 2359               if (transportDebug()) {
 2360                   int bbId = System.identityHashCode(dispatchByteBuffer);
 2361                   StringBuffer sb = new StringBuffer();
 2362                   sb.append(".handleInput: releasing ByteBuffer (" + bbId +
 2363                             ") to ByteBufferPool");
 2364                   dprint(sb.toString());
 2365                }
 2366           }
 2367       }
 2368   }
 2369   
 2370   // End of file.

Save This Page
Home » openjdk-7 » com.sun.corba.se.impl » protocol » [javadoc | source]