1 /*
   2  * Copyright (c) 2002, 2003, 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 org.omg.CORBA.SystemException;
  29 import org.omg.CORBA.OBJ_ADAPTER ;
  30 import org.omg.CORBA.UNKNOWN ;
  31 import org.omg.CORBA.CompletionStatus ;
  32 
  33 import org.omg.CORBA.portable.ServantObject;
  34 
  35 import com.sun.corba.se.pept.protocol.ClientRequestDispatcher;
  36 
  37 import com.sun.corba.se.spi.protocol.LocalClientRequestDispatcher;
  38 import com.sun.corba.se.spi.protocol.LocalClientRequestDispatcherFactory;
  39 import com.sun.corba.se.spi.protocol.ForwardException ;
  40 
  41 import com.sun.corba.se.spi.oa.ObjectAdapter;
  42 import com.sun.corba.se.spi.oa.OAInvocationInfo ;
  43 import com.sun.corba.se.spi.oa.OADestroyed;
  44 
  45 import com.sun.corba.se.spi.orb.ORB;
  46 
  47 import com.sun.corba.se.spi.ior.IOR ;
  48 
  49 import com.sun.corba.se.spi.logging.CORBALogDomains ;
  50 
  51 import com.sun.corba.se.impl.logging.POASystemException ;
  52 import com.sun.corba.se.impl.logging.ORBUtilSystemException ;
  53 
  54 public class POALocalCRDImpl extends LocalClientRequestDispatcherBase
  55 {
  56     private ORBUtilSystemException wrapper ;
  57     private POASystemException poaWrapper ;
  58 
  59     public POALocalCRDImpl( ORB orb, int scid, IOR ior)
  60     {
  61         super( (com.sun.corba.se.spi.orb.ORB)orb, scid, ior );
  62         wrapper = ORBUtilSystemException.get( orb,
  63             CORBALogDomains.RPC_PROTOCOL ) ;
  64         poaWrapper = POASystemException.get( orb,
  65             CORBALogDomains.RPC_PROTOCOL ) ;
  66     }
  67 
  68     private OAInvocationInfo servantEnter( ObjectAdapter oa ) throws OADestroyed
  69     {
  70         oa.enter() ;
  71 
  72         OAInvocationInfo info = oa.makeInvocationInfo( objectId ) ;
  73         orb.pushInvocationInfo( info ) ;
  74 
  75         return info ;
  76     }
  77 
  78     private void servantExit( ObjectAdapter oa )
  79     {
  80         try {
  81             oa.returnServant();
  82         } finally {
  83             oa.exit() ;
  84             orb.popInvocationInfo() ;
  85         }
  86     }
  87 
  88     // Look up the servant for this request and return it in a
  89     // ServantObject.  Note that servant_postinvoke is always called
  90     // by the stub UNLESS this method returns null.  However, in all
  91     // cases we must be sure that ObjectAdapter.getServant and
  92     // ObjectAdapter.returnServant calls are paired, as required for
  93     // Portable Interceptors and Servant Locators in the POA.
  94     // Thus, this method must call returnServant if it returns null.
  95     public ServantObject servant_preinvoke(org.omg.CORBA.Object self,
  96                                            String operation,
  97                                            Class expectedType)
  98     {
  99         ObjectAdapter oa = oaf.find( oaid ) ;
 100         OAInvocationInfo info = null ;
 101 
 102         try {
 103             info = servantEnter( oa ) ;
 104             info.setOperation( operation ) ;
 105         } catch ( OADestroyed ex ) {
 106             // Destroyed POAs can be recreated by normal adapter activation.
 107             // So just reinvoke this method.
 108             return servant_preinvoke(self, operation, expectedType);
 109         }
 110 
 111         try {
 112             try {
 113                 oa.getInvocationServant( info );
 114                 if (!checkForCompatibleServant( info, expectedType ))
 115                     return null ;
 116             } catch (Throwable thr) {
 117                 // Cleanup after this call, then throw to allow
 118                 // outer try to handle the exception appropriately.
 119                 servantExit( oa ) ;
 120                 throw thr ;
 121             }
 122         } catch ( ForwardException ex ) {
 123             /* REVISIT
 124             ClientRequestDispatcher csub = (ClientRequestDispatcher)
 125                 StubAdapter.getDelegate( ex.forward_reference ) ;
 126             IOR ior = csub.getIOR() ;
 127             setLocatedIOR( ior ) ;
 128             */
 129             RuntimeException runexc = new RuntimeException("deal with this.");
 130             runexc.initCause( ex ) ;
 131             throw runexc ;
 132         } catch ( ThreadDeath ex ) {
 133             // ThreadDeath on the server side should not cause a client
 134             // side thread death in the local case.  We want to preserve
 135             // this behavior for location transparency, so that a ThreadDeath
 136             // has the same affect in either the local or remote case.
 137             // The non-colocated case is handled in iiop.ORB.process, which
 138             // throws the same exception.
 139             throw wrapper.runtimeexception( ex ) ;
 140         } catch ( Throwable t ) {
 141             if (t instanceof SystemException)
 142                 throw (SystemException)t ;
 143 
 144             throw poaWrapper.localServantLookup( t ) ;
 145         }
 146 
 147         if (!checkForCompatibleServant( info, expectedType )) {
 148             servantExit( oa ) ;
 149             return null ;
 150         }
 151 
 152         return info;
 153     }
 154 
 155     public void servant_postinvoke(org.omg.CORBA.Object self,
 156                                    ServantObject servantobj)
 157     {
 158         ObjectAdapter oa = orb.peekInvocationInfo().oa() ;
 159         servantExit( oa ) ;
 160     }
 161 }
 162 
 163 // End of file.