Save This Page
Home » openjdk-7 » com.sun.corba.se.impl » protocol » [javadoc | source]
    1   /*
    2    * Copyright (c) 1998, 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    * Licensed Materials - Property of IBM
   27    * RMI-IIOP v1.0
   28    * Copyright IBM Corp. 1998 1999  All Rights Reserved
   29    *
   30    */
   31   
   32   
   33   package com.sun.corba.se.impl.protocol;
   34   
   35   import org.omg.PortableServer.Servant;
   36   
   37   import org.omg.CORBA.SystemException;
   38   import org.omg.CORBA.INTERNAL;
   39   import org.omg.CORBA.UNKNOWN;
   40   import org.omg.CORBA.CompletionStatus;
   41   import org.omg.CORBA.Any;
   42   
   43   import org.omg.CORBA.portable.InvokeHandler;
   44   import org.omg.CORBA.portable.InputStream;
   45   import org.omg.CORBA.portable.OutputStream;
   46   import org.omg.CORBA.portable.UnknownException;
   47   import org.omg.CORBA.portable.ResponseHandler;
   48   
   49   import com.sun.org.omg.SendingContext.CodeBase;
   50   
   51   import com.sun.corba.se.pept.encoding.OutputObject;
   52   import com.sun.corba.se.pept.protocol.MessageMediator;
   53   
   54   import com.sun.corba.se.spi.orb.ORB;
   55   import com.sun.corba.se.spi.orb.ORBVersion;
   56   import com.sun.corba.se.spi.orb.ORBVersionFactory;
   57   import com.sun.corba.se.spi.ior.IOR;
   58   import com.sun.corba.se.spi.ior.ObjectKey;
   59   import com.sun.corba.se.spi.ior.ObjectKeyTemplate;
   60   import com.sun.corba.se.spi.ior.ObjectAdapterId;
   61   import com.sun.corba.se.spi.oa.ObjectAdapterFactory;
   62   import com.sun.corba.se.spi.oa.ObjectAdapter;
   63   import com.sun.corba.se.spi.oa.OAInvocationInfo;
   64   import com.sun.corba.se.spi.oa.OADestroyed;
   65   import com.sun.corba.se.spi.oa.NullServant;
   66   import com.sun.corba.se.spi.protocol.CorbaMessageMediator;
   67   import com.sun.corba.se.spi.protocol.CorbaServerRequestDispatcher;
   68   import com.sun.corba.se.spi.protocol.ForwardException;
   69   import com.sun.corba.se.spi.protocol.RequestDispatcherRegistry;
   70   import com.sun.corba.se.spi.transport.CorbaConnection;
   71   import com.sun.corba.se.spi.logging.CORBALogDomains;
   72   import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
   73   
   74   import com.sun.corba.se.impl.protocol.SpecialMethod;
   75   import com.sun.corba.se.spi.servicecontext.ServiceContext;
   76   import com.sun.corba.se.spi.servicecontext.ServiceContexts;
   77   import com.sun.corba.se.spi.servicecontext.UEInfoServiceContext;
   78   import com.sun.corba.se.spi.servicecontext.CodeSetServiceContext;
   79   import com.sun.corba.se.spi.servicecontext.SendingContextServiceContext;
   80   import com.sun.corba.se.spi.servicecontext.ORBVersionServiceContext;
   81   
   82   import com.sun.corba.se.impl.corba.ServerRequestImpl;
   83   import com.sun.corba.se.impl.encoding.MarshalInputStream;
   84   import com.sun.corba.se.impl.encoding.MarshalOutputStream;
   85   import com.sun.corba.se.impl.encoding.CodeSetComponentInfo;
   86   import com.sun.corba.se.impl.encoding.OSFCodeSetRegistry;
   87   import com.sun.corba.se.impl.orbutil.ORBConstants;
   88   import com.sun.corba.se.impl.orbutil.ORBUtility;
   89   import com.sun.corba.se.impl.protocol.RequestCanceledException;
   90   import com.sun.corba.se.impl.logging.ORBUtilSystemException;
   91   import com.sun.corba.se.impl.logging.POASystemException;
   92   
   93   public class CorbaServerRequestDispatcherImpl
   94       implements CorbaServerRequestDispatcher
   95   {
   96       protected ORB orb; // my ORB instance
   97       private ORBUtilSystemException wrapper ;
   98       private POASystemException poaWrapper ;
   99   
  100       // Added from last version because it broke the build - RTW
  101       // XXX remove me and rebuild: probably no longer needed
  102       // public static final int UNKNOWN_EXCEPTION_INFO_ID = 9;
  103   
  104       public CorbaServerRequestDispatcherImpl(ORB orb)
  105       {
  106           this.orb = orb;
  107           wrapper = ORBUtilSystemException.get( orb,
  108               CORBALogDomains.RPC_PROTOCOL ) ;
  109           poaWrapper = POASystemException.get( orb,
  110               CORBALogDomains.RPC_PROTOCOL ) ;
  111       }
  112   
  113       /** XXX/REVISIT:
  114        * We do not want to look for a servant in the POA/ServantManager case,
  115        * but we could in most other cases.  The OA could have a method that
  116        * returns true if the servant MAY exist, and false only if the servant
  117        * definitely DOES NOT exist.
  118        *
  119        * XXX/REVISIT:
  120        * We may wish to indicate OBJECT_HERE by some mechanism other than
  121        * returning a null result.
  122        *
  123        * Called from ORB.locate when a LocateRequest arrives.
  124        * Result is not always absolutely correct: may indicate OBJECT_HERE
  125        * for non-existent objects, which is resolved on invocation.  This
  126        * "bug" is unavoidable, since in general the object may be destroyed
  127        * between a locate and a request.  Note that this only checks that
  128        * the appropriate ObjectAdapter is available, not that the servant
  129        * actually exists.
  130        * Need to signal one of OBJECT_HERE, OBJECT_FORWARD, OBJECT_NOT_EXIST.
  131        * @return Result is null if object is (possibly) implemented here, otherwise
  132        * an IOR indicating objref to forward the request to.
  133        * @exception OBJECT_NOT_EXIST is thrown if we know the object does not
  134        * exist here, and we are not forwarding.
  135        */
  136       public IOR locate(ObjectKey okey)
  137       {
  138           try {
  139               if (orb.subcontractDebugFlag)
  140                   dprint(".locate->");
  141   
  142               ObjectKeyTemplate oktemp = okey.getTemplate() ;
  143   
  144               try {
  145                   checkServerId(okey);
  146               } catch (ForwardException fex) {
  147                   return fex.getIOR() ;
  148               }
  149   
  150               // Called only for its side-effect of throwing appropriate exceptions
  151               findObjectAdapter(oktemp);
  152   
  153               return null ;
  154           } finally {
  155               if (orb.subcontractDebugFlag)
  156                   dprint(".locate<-");
  157           }
  158       }
  159   
  160       public void dispatch(MessageMediator messageMediator)
  161       {
  162           CorbaMessageMediator request = (CorbaMessageMediator) messageMediator;
  163           try {
  164               if (orb.subcontractDebugFlag) {
  165                   dprint(".dispatch->: " + opAndId(request));
  166               }
  167   
  168               // to set the codebase information, if any transmitted; and also
  169               // appropriate ORB Version.
  170               consumeServiceContexts(request);
  171   
  172               // Now that we have the service contexts processed and the
  173               // correct ORBVersion set, we must finish initializing the
  174               // stream.
  175               ((MarshalInputStream)request.getInputObject())
  176                   .performORBVersionSpecificInit();
  177   
  178               ObjectKey okey = request.getObjectKey();
  179   
  180               // Check that this server is the right server
  181               try {
  182                   checkServerId(okey);
  183               } catch (ForwardException fex) {
  184                   if (orb.subcontractDebugFlag) {
  185                       dprint(".dispatch: " + opAndId(request)
  186                              + ": bad server id");
  187                   }
  188   
  189                   request.getProtocolHandler()
  190                       .createLocationForward(request, fex.getIOR(), null);
  191                   return;
  192               }
  193   
  194               String operation = request.getOperationName();
  195               ObjectAdapter objectAdapter = null ;
  196   
  197               try {
  198                   byte[] objectId = okey.getId().getId() ;
  199                   ObjectKeyTemplate oktemp = okey.getTemplate() ;
  200                   objectAdapter = findObjectAdapter(oktemp);
  201   
  202                   java.lang.Object servant = getServantWithPI(request, objectAdapter,
  203                       objectId, oktemp, operation);
  204   
  205                   dispatchToServant(servant, request, objectId, objectAdapter);
  206               } catch (ForwardException ex) {
  207                   if (orb.subcontractDebugFlag) {
  208                       dprint(".dispatch: " + opAndId(request)
  209                              + ": ForwardException caught");
  210                   }
  211   
  212                   // Thrown by Portable Interceptors from InterceptorInvoker,
  213                   // through Response constructor.
  214                   request.getProtocolHandler()
  215                       .createLocationForward(request, ex.getIOR(), null);
  216               } catch (OADestroyed ex) {
  217                   if (orb.subcontractDebugFlag) {
  218                       dprint(".dispatch: " + opAndId(request)
  219                              + ": OADestroyed exception caught");
  220                   }
  221   
  222                   // DO NOT CALL THIS HERE:
  223                   // releaseServant(objectAdapter);
  224                   // The problem is that OADestroyed is only thrown by oa.enter, in
  225                   // which case oa.exit should NOT be called, and neither should
  226                   // the invocationInfo stack be popped.
  227   
  228                   // Destroyed POAs can be recreated by normal adapter activation.
  229                   // So just restart the dispatch.
  230                   dispatch(request);
  231               } catch (RequestCanceledException ex) {
  232                   if (orb.subcontractDebugFlag) {
  233                       dprint(".dispatch: " + opAndId(request)
  234                              + ": RequestCanceledException caught");
  235                   }
  236   
  237                   // IDLJ generated non-tie based skeletons do not catch the
  238                   // RequestCanceledException. Rethrow the exception, which will
  239                   // cause the worker thread to unwind the dispatch and wait for
  240                   // other requests.
  241                   throw ex;
  242               } catch (UnknownException ex) {
  243                   if (orb.subcontractDebugFlag) {
  244                       dprint(".dispatch: " + opAndId(request)
  245                              + ": UnknownException caught " + ex);
  246                   }
  247   
  248                   // RMIC generated tie skeletons convert all Throwable exception
  249                   // types (including RequestCanceledException, ThreadDeath)
  250                   // thrown during reading fragments into UnknownException.
  251                   // If RequestCanceledException was indeed raised,
  252                   // then rethrow it, which will eventually cause the worker
  253                   // thread to unstack the dispatch and wait for other requests.
  254                   if (ex.originalEx instanceof RequestCanceledException) {
  255                       throw (RequestCanceledException) ex.originalEx;
  256                   }
  257   
  258                   ServiceContexts contexts = new ServiceContexts(orb);
  259                   UEInfoServiceContext usc = new UEInfoServiceContext(
  260                       ex.originalEx);
  261   
  262                   contexts.put( usc ) ;
  263   
  264                   SystemException sysex = wrapper.unknownExceptionInDispatch(
  265                           CompletionStatus.COMPLETED_MAYBE, ex ) ;
  266                   request.getProtocolHandler()
  267                       .createSystemExceptionResponse(request, sysex,
  268                           contexts);
  269               } catch (Throwable ex) {
  270                   if (orb.subcontractDebugFlag) {
  271                       dprint(".dispatch: " + opAndId(request)
  272                              + ": other exception " + ex);
  273                   }
  274                   request.getProtocolHandler()
  275                       .handleThrowableDuringServerDispatch(
  276                           request, ex, CompletionStatus.COMPLETED_MAYBE);
  277               }
  278               return;
  279           } finally {
  280               if (orb.subcontractDebugFlag) {
  281                   dprint(".dispatch<-: " + opAndId(request));
  282               }
  283           }
  284       }
  285   
  286       private void releaseServant(ObjectAdapter objectAdapter)
  287       {
  288           try {
  289               if (orb.subcontractDebugFlag) {
  290                   dprint(".releaseServant->");
  291               }
  292   
  293               if (objectAdapter == null) {
  294                   if (orb.subcontractDebugFlag) {
  295                       dprint(".releaseServant: null object adapter");
  296                   }
  297                   return ;
  298               }
  299   
  300               try {
  301                   objectAdapter.returnServant();
  302               } finally {
  303                   objectAdapter.exit();
  304                   orb.popInvocationInfo() ;
  305               }
  306           } finally {
  307               if (orb.subcontractDebugFlag) {
  308                   dprint(".releaseServant<-");
  309               }
  310           }
  311       }
  312   
  313       // Note that objectAdapter.enter() must be called before getServant.
  314       private java.lang.Object getServant(ObjectAdapter objectAdapter, byte[] objectId,
  315           String operation)
  316           throws OADestroyed
  317       {
  318           try {
  319               if (orb.subcontractDebugFlag) {
  320                   dprint(".getServant->");
  321               }
  322   
  323               OAInvocationInfo info = objectAdapter.makeInvocationInfo(objectId);
  324               info.setOperation(operation);
  325               orb.pushInvocationInfo(info);
  326               objectAdapter.getInvocationServant(info);
  327               return info.getServantContainer() ;
  328           } finally {
  329               if (orb.subcontractDebugFlag) {
  330                   dprint(".getServant<-");
  331               }
  332           }
  333       }
  334   
  335       protected java.lang.Object getServantWithPI(CorbaMessageMediator request,
  336                                                    ObjectAdapter objectAdapter,
  337           byte[] objectId, ObjectKeyTemplate oktemp, String operation)
  338           throws OADestroyed
  339       {
  340           try {
  341               if (orb.subcontractDebugFlag) {
  342                   dprint(".getServantWithPI->");
  343               }
  344   
  345               // Prepare Portable Interceptors for a new server request
  346               // and invoke receive_request_service_contexts.  The starting
  347               // point may throw a SystemException or ForwardException.
  348               orb.getPIHandler().initializeServerPIInfo(request, objectAdapter,
  349                   objectId, oktemp);
  350               orb.getPIHandler().invokeServerPIStartingPoint();
  351   
  352               objectAdapter.enter() ;
  353   
  354               // This must be set just after the enter so that exceptions thrown by
  355               // enter do not cause
  356               // the exception reply to pop the thread stack and do an extra oa.exit.
  357               if (request != null)
  358                   request.setExecuteReturnServantInResponseConstructor(true);
  359   
  360               java.lang.Object servant = getServant(objectAdapter, objectId,
  361                   operation);
  362   
  363               // Note: we do not know the MDI on a null servant.
  364               // We only end up in that situation if _non_existent called,
  365               // so that the following handleNullServant call does not throw an
  366               // exception.
  367               String mdi = "unknown" ;
  368   
  369               if (servant instanceof NullServant)
  370                   handleNullServant(operation, (NullServant)servant);
  371               else
  372                   mdi = objectAdapter.getInterfaces(servant, objectId)[0] ;
  373   
  374               orb.getPIHandler().setServerPIInfo(servant, mdi);
  375   
  376               if (((servant != null) &&
  377                   !(servant instanceof org.omg.CORBA.DynamicImplementation) &&
  378                   !(servant instanceof org.omg.PortableServer.DynamicImplementation)) ||
  379                   (SpecialMethod.getSpecialMethod(operation) != null)) {
  380                   orb.getPIHandler().invokeServerPIIntermediatePoint();
  381               }
  382   
  383               return servant ;
  384           } finally {
  385               if (orb.subcontractDebugFlag) {
  386                   dprint(".getServantWithPI<-");
  387               }
  388           }
  389       }
  390   
  391       protected void checkServerId(ObjectKey okey)
  392       {
  393           try {
  394               if (orb.subcontractDebugFlag) {
  395                   dprint(".checkServerId->");
  396               }
  397   
  398               ObjectKeyTemplate oktemp = okey.getTemplate() ;
  399               int sId = oktemp.getServerId() ;
  400               int scid = oktemp.getSubcontractId() ;
  401   
  402               if (!orb.isLocalServerId(scid, sId)) {
  403                   if (orb.subcontractDebugFlag) {
  404                       dprint(".checkServerId: bad server id");
  405                   }
  406   
  407                   orb.handleBadServerId(okey);
  408               }
  409           } finally {
  410               if (orb.subcontractDebugFlag) {
  411                   dprint(".checkServerId<-");
  412               }
  413           }
  414       }
  415   
  416       private ObjectAdapter findObjectAdapter(ObjectKeyTemplate oktemp)
  417       {
  418           try {
  419               if (orb.subcontractDebugFlag) {
  420                   dprint(".findObjectAdapter->");
  421               }
  422   
  423               RequestDispatcherRegistry scr = orb.getRequestDispatcherRegistry() ;
  424               int scid = oktemp.getSubcontractId() ;
  425               ObjectAdapterFactory oaf = scr.getObjectAdapterFactory(scid);
  426               if (oaf == null) {
  427                   if (orb.subcontractDebugFlag) {
  428                       dprint(".findObjectAdapter: failed to find ObjectAdapterFactory");
  429                   }
  430   
  431                   throw wrapper.noObjectAdapterFactory() ;
  432               }
  433   
  434               ObjectAdapterId oaid = oktemp.getObjectAdapterId() ;
  435               ObjectAdapter oa = oaf.find(oaid);
  436   
  437               if (oa == null) {
  438                   if (orb.subcontractDebugFlag) {
  439                       dprint(".findObjectAdapter: failed to find ObjectAdaptor");
  440                   }
  441   
  442                   throw wrapper.badAdapterId() ;
  443               }
  444   
  445               return oa ;
  446           } finally {
  447               if (orb.subcontractDebugFlag) {
  448                   dprint(".findObjectAdapter<-");
  449               }
  450           }
  451       }
  452   
  453       /** Always throws OBJECT_NOT_EXIST if operation is not a special method.
  454       * If operation is _non_existent or _not_existent, this will just
  455       * return without performing any action, so that _non_existent can return
  456       * false.  Always throws OBJECT_NOT_EXIST for any other special method.
  457       * Update for issue 4385.
  458       */
  459       protected void handleNullServant(String operation, NullServant nserv )
  460       {
  461           try {
  462               if (orb.subcontractDebugFlag) {
  463                   dprint(".handleNullServant->: " + operation);
  464               }
  465   
  466               SpecialMethod specialMethod =
  467                   SpecialMethod.getSpecialMethod(operation);
  468   
  469               if ((specialMethod == null) ||
  470                   !specialMethod.isNonExistentMethod()) {
  471                   if (orb.subcontractDebugFlag) {
  472                       dprint(".handleNullServant: " + operation
  473                              + ": throwing OBJECT_NOT_EXIST");
  474                   }
  475   
  476                   throw nserv.getException() ;
  477               }
  478           } finally {
  479               if (orb.subcontractDebugFlag) {
  480                   dprint(".handleNullServant<-: " + operation);
  481               }
  482           }
  483       }
  484   
  485       protected void consumeServiceContexts(CorbaMessageMediator request)
  486       {
  487           try {
  488               if (orb.subcontractDebugFlag) {
  489                   dprint(".consumeServiceContexts->: "
  490                          + opAndId(request));
  491               }
  492   
  493               ServiceContexts ctxts = request.getRequestServiceContexts();
  494               ServiceContext sc ;
  495   
  496               GIOPVersion giopVersion = request.getGIOPVersion();
  497   
  498               // we cannot depend on this since for our local case, we do not send
  499               // in this service context.  Can we rely on just the CodeSetServiceContext?
  500               // boolean rtSC = false; // Runtime ServiceContext
  501   
  502               boolean hasCodeSetContext = processCodeSetContext(request, ctxts);
  503   
  504               if (orb.subcontractDebugFlag) {
  505                   dprint(".consumeServiceContexts: " + opAndId(request)
  506                          + ": GIOP version: " + giopVersion);
  507                   dprint(".consumeServiceContexts: " + opAndId(request)
  508                          + ": as code set context? " + hasCodeSetContext);
  509               }
  510   
  511               sc = ctxts.get(
  512                   SendingContextServiceContext.SERVICE_CONTEXT_ID ) ;
  513   
  514               if (sc != null) {
  515                   SendingContextServiceContext scsc =
  516                       (SendingContextServiceContext)sc ;
  517                   IOR ior = scsc.getIOR() ;
  518   
  519                   try {
  520                       ((CorbaConnection)request.getConnection())
  521                           .setCodeBaseIOR(ior);
  522                   } catch (ThreadDeath td) {
  523                       throw td ;
  524                   } catch (Throwable t) {
  525                       throw wrapper.badStringifiedIor( t ) ;
  526                   }
  527               }
  528   
  529               // the RTSC is sent only once during session establishment.  We
  530               // need to find out if the CodeBaseRef is already set.  If yes,
  531               // then also the rtSC flag needs to be set to true
  532               // this is not possible for the LocalCase since there is no
  533               // IIOPConnection for the LocalCase
  534   
  535               // used for a case where we have JDK 1.3 supporting 1.0 protocol,
  536               // but sending 2 service contexts, that is not normal as per
  537               // GIOP rules, based on above information, we figure out that we
  538               // are talking to the legacy ORB and set the ORB Version Accordingly.
  539   
  540               // this special case tell us that it is legacy SUN orb
  541               // and not a foreign one
  542               // rtSC is not available for localcase due to which this generic
  543               // path would fail if relying on rtSC
  544               //if (giopVersion.equals(GIOPVersion.V1_0) && hasCodeSetContext && rtSC)
  545               boolean isForeignORB = false;
  546   
  547               if (giopVersion.equals(GIOPVersion.V1_0) && hasCodeSetContext) {
  548                   if (orb.subcontractDebugFlag) {
  549                       dprint(".consumeServiceCOntexts: " + opAndId(request)
  550                              + ": Determined to be an old Sun ORB");
  551                   }
  552   
  553                   orb.setORBVersion(ORBVersionFactory.getOLD()) ;
  554                   // System.out.println("setting legacy ORB version");
  555               } else {
  556                   // If it didn't include our ORB version service context (below),
  557                   // then it must be a foreign ORB.
  558                   isForeignORB = true;
  559               }
  560   
  561               // try to get the ORBVersion sent as part of the ServiceContext
  562               // if any
  563               sc = ctxts.get( ORBVersionServiceContext.SERVICE_CONTEXT_ID ) ;
  564               if (sc != null) {
  565                   ORBVersionServiceContext ovsc =
  566                      (ORBVersionServiceContext) sc;
  567   
  568                   ORBVersion version = ovsc.getVersion();
  569                   orb.setORBVersion(version);
  570   
  571                   isForeignORB = false;
  572               }
  573   
  574               if (isForeignORB) {
  575                   if (orb.subcontractDebugFlag) {
  576                       dprint(".consumeServiceContexts: " + opAndId(request)
  577                              + ": Determined to be a foreign ORB");
  578                   }
  579   
  580                   orb.setORBVersion(ORBVersionFactory.getFOREIGN());
  581               }
  582           } finally {
  583               if (orb.subcontractDebugFlag) {
  584                   dprint(".consumeServiceContexts<-: " + opAndId(request));
  585               }
  586           }
  587       }
  588   
  589       protected CorbaMessageMediator dispatchToServant(
  590           java.lang.Object servant,
  591           CorbaMessageMediator req,
  592           byte[] objectId, ObjectAdapter objectAdapter)
  593       {
  594           try {
  595               if (orb.subcontractDebugFlag) {
  596                   dprint(".dispatchToServant->: " + opAndId(req));
  597               }
  598   
  599               CorbaMessageMediator response = null ;
  600   
  601               String operation = req.getOperationName() ;
  602   
  603               SpecialMethod method = SpecialMethod.getSpecialMethod(operation) ;
  604               if (method != null) {
  605                   if (orb.subcontractDebugFlag) {
  606                       dprint(".dispatchToServant: " + opAndId(req)
  607                              + ": Handling special method");
  608                   }
  609   
  610                   response = method.invoke(servant, req, objectId, objectAdapter);
  611                   return response ;
  612               }
  613   
  614               // Invoke on the servant using the portable DSI skeleton
  615               if (servant instanceof org.omg.CORBA.DynamicImplementation) {
  616                   if (orb.subcontractDebugFlag) {
  617                       dprint(".dispatchToServant: " + opAndId(req)
  618                              + ": Handling old style DSI type servant");
  619                   }
  620   
  621                   org.omg.CORBA.DynamicImplementation dynimpl =
  622                       (org.omg.CORBA.DynamicImplementation)servant;
  623                   ServerRequestImpl sreq = new ServerRequestImpl(req, orb);
  624   
  625                   // Note: When/if dynimpl.invoke calls arguments() or
  626                   // set_exception() then intermediate points are run.
  627                   dynimpl.invoke(sreq);
  628   
  629                   response = handleDynamicResult(sreq, req);
  630               } else if (servant instanceof org.omg.PortableServer.DynamicImplementation) {
  631                   if (orb.subcontractDebugFlag) {
  632                       dprint(".dispatchToServant: " + opAndId(req)
  633                              + ": Handling POA DSI type servant");
  634                   }
  635   
  636                   org.omg.PortableServer.DynamicImplementation dynimpl =
  637                       (org.omg.PortableServer.DynamicImplementation)servant;
  638                   ServerRequestImpl sreq = new ServerRequestImpl(req, orb);
  639   
  640                   // Note: When/if dynimpl.invoke calls arguments() or
  641                   // set_exception() then intermediate points are run.
  642                   dynimpl.invoke(sreq);
  643   
  644                   response = handleDynamicResult(sreq, req);
  645               } else {
  646                   if (orb.subcontractDebugFlag) {
  647                       dprint(".dispatchToServant: " + opAndId(req)
  648                              + ": Handling invoke handler type servant");
  649                   }
  650   
  651                   InvokeHandler invhandle = (InvokeHandler)servant ;
  652   
  653                   OutputStream stream =
  654                       (OutputStream)invhandle._invoke(
  655                         operation,
  656                         (org.omg.CORBA.portable.InputStream)req.getInputObject(),
  657                         req);
  658                   response = (CorbaMessageMediator)
  659                       ((OutputObject)stream).getMessageMediator();
  660               }
  661   
  662               return response ;
  663           } finally {
  664               if (orb.subcontractDebugFlag) {
  665                   dprint(".dispatchToServant<-: " + opAndId(req));
  666               }
  667           }
  668       }
  669   
  670       protected CorbaMessageMediator handleDynamicResult(
  671           ServerRequestImpl sreq,
  672           CorbaMessageMediator req)
  673       {
  674           try {
  675               if (orb.subcontractDebugFlag) {
  676                   dprint(".handleDynamicResult->: " + opAndId(req));
  677               }
  678   
  679               CorbaMessageMediator response = null ;
  680   
  681               // Check if ServerRequestImpl.result() has been called
  682               Any excany = sreq.checkResultCalled();
  683   
  684               if (excany == null) { // normal return
  685                   if (orb.subcontractDebugFlag) {
  686                       dprint(".handleDynamicResult: " + opAndId(req)
  687                              + ": handling normal result");
  688                   }
  689   
  690                   // Marshal out/inout/return parameters into the ReplyMessage
  691                   response = sendingReply(req);
  692                   OutputStream os = (OutputStream) response.getOutputObject();
  693                   sreq.marshalReplyParams(os);
  694               }  else {
  695                   if (orb.subcontractDebugFlag) {
  696                       dprint(".handleDynamicResult: " + opAndId(req)
  697                              + ": handling error");
  698                   }
  699   
  700                   response = sendingReply(req, excany);
  701               }
  702   
  703               return response ;
  704           } finally {
  705               if (orb.subcontractDebugFlag) {
  706                   dprint(".handleDynamicResult<-: " + opAndId(req));
  707               }
  708           }
  709       }
  710   
  711       protected CorbaMessageMediator sendingReply(CorbaMessageMediator req)
  712       {
  713           try {
  714               if (orb.subcontractDebugFlag) {
  715                   dprint(".sendingReply->: " + opAndId(req));
  716               }
  717   
  718               ServiceContexts scs = new ServiceContexts(orb);
  719               return req.getProtocolHandler().createResponse(req, scs);
  720           } finally {
  721               if (orb.subcontractDebugFlag) {
  722                   dprint(".sendingReply<-: " + opAndId(req));
  723               }
  724           }
  725       }
  726   
  727       /** Must always be called, just after the servant's method returns.
  728        *  Creates the ReplyMessage header and puts in the transaction context
  729        *  if necessary.
  730        */
  731       protected CorbaMessageMediator sendingReply(CorbaMessageMediator req, Any excany)
  732       {
  733           try {
  734               if (orb.subcontractDebugFlag) {
  735                   dprint(".sendingReply/Any->: " + opAndId(req));
  736               }
  737   
  738               ServiceContexts scs = new ServiceContexts(orb);
  739   
  740               // Check if the servant set a SystemException or
  741               // UserException
  742               CorbaMessageMediator resp;
  743               String repId=null;
  744               try {
  745                   repId = excany.type().id();
  746               } catch (org.omg.CORBA.TypeCodePackage.BadKind e) {
  747                   throw wrapper.problemWithExceptionTypecode( e ) ;
  748               }
  749   
  750               if (ORBUtility.isSystemException(repId)) {
  751                   if (orb.subcontractDebugFlag) {
  752                       dprint(".sendingReply/Any: " + opAndId(req)
  753                              + ": handling system exception");
  754                   }
  755   
  756                   // Get the exception object from the Any
  757                   InputStream in = excany.create_input_stream();
  758                   SystemException ex = ORBUtility.readSystemException(in);
  759                   // Marshal the exception back
  760                   resp = req.getProtocolHandler()
  761                       .createSystemExceptionResponse(req, ex, scs);
  762               } else {
  763                   if (orb.subcontractDebugFlag) {
  764                       dprint(".sendingReply/Any: " + opAndId(req)
  765                              + ": handling user exception");
  766                   }
  767   
  768                   resp = req.getProtocolHandler()
  769                       .createUserExceptionResponse(req, scs);
  770                   OutputStream os = (OutputStream)resp.getOutputObject();
  771                   excany.write_value(os);
  772               }
  773   
  774               return resp;
  775           } finally {
  776               if (orb.subcontractDebugFlag) {
  777                   dprint(".sendingReply/Any<-: " + opAndId(req));
  778               }
  779           }
  780       }
  781   
  782       /**
  783        * Handles setting the connection's code sets if required.
  784        * Returns true if the CodeSetContext was in the request, false
  785        * otherwise.
  786        */
  787       protected boolean processCodeSetContext(
  788           CorbaMessageMediator request, ServiceContexts contexts)
  789       {
  790           try {
  791               if (orb.subcontractDebugFlag) {
  792                   dprint(".processCodeSetContext->: " + opAndId(request));
  793               }
  794   
  795               ServiceContext sc = contexts.get(
  796                   CodeSetServiceContext.SERVICE_CONTEXT_ID);
  797               if (sc != null) {
  798                   // Somehow a code set service context showed up in the local case.
  799                   if (request.getConnection() == null) {
  800                       return true;
  801                   }
  802   
  803                   // If it's GIOP 1.0, it shouldn't have this context at all.  Our legacy
  804                   // ORBs sent it and we need to know if it's here to make ORB versioning
  805                   // decisions, but we don't use the contents.
  806                   if (request.getGIOPVersion().equals(GIOPVersion.V1_0)) {
  807                       return true;
  808                   }
  809   
  810                   CodeSetServiceContext cssc = (CodeSetServiceContext)sc ;
  811                   CodeSetComponentInfo.CodeSetContext csctx = cssc.getCodeSetContext();
  812   
  813                   // Note on threading:
  814                   //
  815                   // getCodeSetContext and setCodeSetContext are synchronized
  816                   // on the Connection.  At worst, this will result in
  817                   // multiple threads entering this block and calling
  818                   // setCodeSetContext but not actually changing the
  819                   // values on the Connection.
  820                   //
  821                   // Alternative would be to lock the connection for the
  822                   // whole block, but it's fine either way.
  823   
  824                   // The connection's codeSetContext is null until we've received a
  825                   // request with a code set context with the negotiated code sets.
  826                   if (((CorbaConnection)request.getConnection())
  827                       .getCodeSetContext() == null)
  828                   {
  829   
  830                       // Use these code sets on this connection
  831                       if (orb.subcontractDebugFlag) {
  832                           dprint(".processCodeSetContext: " + opAndId(request)
  833                                  + ": Setting code sets to: " + csctx);
  834                       }
  835   
  836                       ((CorbaConnection)request.getConnection())
  837                           .setCodeSetContext(csctx);
  838   
  839                       // We had to read the method name using ISO 8859-1
  840                       // (which is the default in the CDRInputStream for
  841                       // char data), but now we may have a new char
  842                       // code set.  If it isn't ISO8859-1, we must tell
  843                       // the CDR stream to null any converter references
  844                       // it has created so that it will reacquire
  845                       // the code sets again using the new info.
  846                       //
  847                       // This should probably compare with the stream's
  848                       // char code set rather than assuming it's ISO8859-1.
  849                       // (However, the operation name is almost certainly
  850                       // ISO8859-1 or ASCII.)
  851                       if (csctx.getCharCodeSet() !=
  852                           OSFCodeSetRegistry.ISO_8859_1.getNumber()) {
  853                           ((MarshalInputStream)request.getInputObject())
  854                               .resetCodeSetConverters();
  855                       }
  856                   }
  857               }
  858   
  859               // If no code set information is ever sent from the client,
  860               // the server will use ISO8859-1 for char and throw an
  861               // exception for any wchar transmissions.
  862               //
  863               // In the local case, we use ORB provided streams for
  864               // marshaling and unmarshaling.  Currently, they use
  865               // ISO8859-1 for char/string and UTF16 for wchar/wstring.
  866               return sc != null ;
  867           } finally {
  868               if (orb.subcontractDebugFlag) {
  869                   dprint(".processCodeSetContext<-: " + opAndId(request));
  870               }
  871           }
  872       }
  873   
  874       protected void dprint(String msg)
  875       {
  876           ORBUtility.dprint("CorbaServerRequestDispatcherImpl", msg);
  877       }
  878   
  879       protected String opAndId(CorbaMessageMediator mediator)
  880       {
  881           return ORBUtility.operationNameAndRequestId(mediator);
  882       }
  883   }
  884   
  885   // End of file.

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