POALocalCRDImpl.java revision 608:7e06bf1dcb09
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
26package com.sun.corba.se.impl.protocol;
27
28import org.omg.CORBA.SystemException;
29import org.omg.CORBA.OBJ_ADAPTER ;
30import org.omg.CORBA.UNKNOWN ;
31import org.omg.CORBA.CompletionStatus ;
32
33import org.omg.CORBA.portable.ServantObject;
34
35import com.sun.corba.se.pept.protocol.ClientRequestDispatcher;
36
37import com.sun.corba.se.spi.protocol.LocalClientRequestDispatcher;
38import com.sun.corba.se.spi.protocol.LocalClientRequestDispatcherFactory;
39import com.sun.corba.se.spi.protocol.ForwardException ;
40
41import com.sun.corba.se.spi.oa.ObjectAdapter;
42import com.sun.corba.se.spi.oa.OAInvocationInfo ;
43import com.sun.corba.se.spi.oa.OADestroyed;
44
45import com.sun.corba.se.spi.orb.ORB;
46
47import com.sun.corba.se.spi.ior.IOR ;
48
49import com.sun.corba.se.spi.logging.CORBALogDomains ;
50
51import com.sun.corba.se.impl.logging.POASystemException ;
52import com.sun.corba.se.impl.logging.ORBUtilSystemException ;
53
54public 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.
164