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.oa.toa ;
  27 
  28 import org.omg.CORBA.Policy ;
  29 import org.omg.PortableInterceptor.ObjectReferenceTemplate ;
  30 import org.omg.PortableInterceptor.ObjectReferenceFactory ;
  31 import org.omg.PortableInterceptor.ACTIVE;
  32 import org.omg.PortableServer.ServantLocatorPackage.CookieHolder ;
  33 
  34 import com.sun.corba.se.pept.protocol.ClientDelegate ;
  35 
  36 import com.sun.corba.se.spi.copyobject.CopierManager ;
  37 import com.sun.corba.se.spi.copyobject.ObjectCopier ;
  38 import com.sun.corba.se.spi.copyobject.ObjectCopierFactory ;
  39 import com.sun.corba.se.spi.ior.ObjectKeyTemplate ;
  40 import com.sun.corba.se.spi.ior.iiop.IIOPAddress ;
  41 import com.sun.corba.se.spi.ior.iiop.IIOPFactories ;
  42 import com.sun.corba.se.spi.oa.OAInvocationInfo ;
  43 import com.sun.corba.se.spi.oa.OADestroyed ;
  44 import com.sun.corba.se.spi.oa.ObjectAdapterBase ;
  45 import com.sun.corba.se.spi.orb.ORB ;
  46 import com.sun.corba.se.spi.presentation.rmi.StubAdapter ;
  47 import com.sun.corba.se.spi.protocol.RequestDispatcherRegistry ;
  48 import com.sun.corba.se.spi.protocol.LocalClientRequestDispatcher ;
  49 import com.sun.corba.se.spi.transport.CorbaContactInfoList ;
  50 
  51 import com.sun.corba.se.impl.ior.JIDLObjectKeyTemplate ;
  52 import com.sun.corba.se.impl.oa.NullServantImpl;
  53 import com.sun.corba.se.impl.oa.poa.Policies;
  54 import com.sun.corba.se.impl.oa.toa.TransientObjectManager ;
  55 import com.sun.corba.se.impl.orbutil.ORBConstants ;
  56 import com.sun.corba.se.impl.protocol.JIDLLocalCRDImpl ;
  57 
  58 /** The Transient Object Adapter (TOA) represents the OA for purely transient
  59 * objects.  It is used for standard RMI-IIOP as well as backwards compatible
  60 * server support (i.e. the ORB.connect() method)
  61 * Its characteristics include:
  62 * <UL>
  63 * <LI>There is only one OA instance of the TOA.  Its OAId is { "TOA" }</LI>
  64 * <LI>There is not adapter manager.  The TOA manager ID is fixed.<LI>
  65 * <LI>State is the same as ORB state (TBD)</LI>
  66 * </UL>
  67 * Other requirements:
  68 * <UL>
  69 * <LI>All object adapters must invoke ORB.adapterCreated when they are created.
  70 * </LI>
  71 * <LI>All adapter managers must invoke ORB.adapterManagerStateChanged when
  72 * their state changes, mapping the internal state to an ORT state.</LI>
  73 * <LI>AdapterStateChanged must be invoked (from somewhere) whenever
  74 * an adapter state changes that is not due to an adapter manager state change.</LI>
  75 * </UL>
  76 */
  77 public class TOAImpl extends ObjectAdapterBase implements TOA
  78 {
  79     private TransientObjectManager servants ;
  80 
  81     public TOAImpl( ORB orb, TransientObjectManager tom, String codebase )
  82     {
  83         super( orb ) ;
  84         servants = tom ;
  85 
  86         // Make the object key template
  87         int serverid = ((ORB)getORB()).getTransientServerId();
  88         int scid = ORBConstants.TOA_SCID ;
  89 
  90         ObjectKeyTemplate oktemp = new JIDLObjectKeyTemplate( orb, scid, serverid ) ;
  91 
  92         // REVISIT - POA specific
  93         Policies policies = Policies.defaultPolicies;
  94 
  95         // REVISIT - absorb codebase into a policy
  96         initializeTemplate( oktemp, true,
  97                             policies,
  98                             codebase,
  99                             null, // manager id
 100                             oktemp.getObjectAdapterId()
 101                             ) ;
 102     }
 103 
 104     // Methods required for dispatching requests
 105 
 106     public ObjectCopierFactory getObjectCopierFactory()
 107     {
 108         CopierManager cm = getORB().getCopierManager() ;
 109         return cm.getDefaultObjectCopierFactory() ;
 110     }
 111 
 112     public org.omg.CORBA.Object getLocalServant( byte[] objectId )
 113     {
 114         return (org.omg.CORBA.Object)(servants.lookupServant( objectId ) ) ;
 115     }
 116 
 117     /** Get the servant for the request given by the parameters.
 118     * This will update thread Current, so that subsequent calls to
 119     * returnServant and removeCurrent from the same thread are for the
 120     * same request.
 121     * @param request is the request containing the rest of the request
 122     */
 123     public void getInvocationServant( OAInvocationInfo info )
 124     {
 125         java.lang.Object servant = servants.lookupServant( info.id() ) ;
 126         if (servant == null)
 127             // This is expected to result in an RMI-IIOP NoSuchObjectException.
 128             // See bug 4973160.
 129             servant = new NullServantImpl( lifecycleWrapper().nullServant() ) ;
 130         info.setServant( servant ) ;
 131     }
 132 
 133     public void returnServant()
 134     {
 135         // NO-OP
 136     }
 137 
 138     /** Return the most derived interface for the given servant and objectId.
 139     */
 140     public String[] getInterfaces( Object servant, byte[] objectId )
 141     {
 142         return StubAdapter.getTypeIds( servant ) ;
 143     }
 144 
 145     // XXX For now, this does nothing.
 146     // This will need fixing once we support ORB and thread level policies,
 147     // but for now, there is no way to associate policies with the TOA, so
 148     // getEffectivePolicy must always return null.
 149     public Policy getEffectivePolicy( int type )
 150     {
 151         return null ;
 152     }
 153 
 154     public int getManagerId()
 155     {
 156         return -1 ;
 157     }
 158 
 159     public short getState()
 160     {
 161         return ACTIVE.value ;
 162     }
 163 
 164     public void enter() throws OADestroyed
 165     {
 166     }
 167 
 168     public void exit()
 169     {
 170     }
 171 
 172     // Methods unique to the TOA
 173 
 174     public void connect( org.omg.CORBA.Object objref)
 175     {
 176         // Store the objref and get a userkey allocated by the transient
 177         // object manager.
 178         byte[] key = servants.storeServant(objref, null);
 179 
 180         // Find out the repository ID for this objref.
 181         String id = StubAdapter.getTypeIds( objref )[0] ;
 182 
 183         // Create the new objref
 184         ObjectReferenceFactory orf = getCurrentFactory() ;
 185         org.omg.CORBA.Object obj = orf.make_object( id, key ) ;
 186 
 187         // Copy the delegate from the new objref to the argument
 188         // XXX handle the case of an attempt to connect a local object.
 189 
 190         org.omg.CORBA.portable.Delegate delegate = StubAdapter.getDelegate(
 191             obj ) ;
 192         CorbaContactInfoList ccil = (CorbaContactInfoList)
 193             ((ClientDelegate)delegate).getContactInfoList() ;
 194         LocalClientRequestDispatcher lcs =
 195             ccil.getLocalClientRequestDispatcher() ;
 196 
 197         if (lcs instanceof JIDLLocalCRDImpl) {
 198             JIDLLocalCRDImpl jlcs = (JIDLLocalCRDImpl)lcs ;
 199             jlcs.setServant( objref ) ;
 200         } else {
 201             throw new RuntimeException(
 202                 "TOAImpl.connect can not be called on " + lcs ) ;
 203         }
 204 
 205         StubAdapter.setDelegate( objref, delegate ) ;
 206     }
 207 
 208     public void disconnect( org.omg.CORBA.Object objref )
 209     {
 210         // Get the delegate, then ior, then transientKey, then delete servant
 211         org.omg.CORBA.portable.Delegate del = StubAdapter.getDelegate(
 212             objref ) ;
 213         CorbaContactInfoList ccil = (CorbaContactInfoList)
 214             ((ClientDelegate)del).getContactInfoList() ;
 215         LocalClientRequestDispatcher lcs =
 216             ccil.getLocalClientRequestDispatcher() ;
 217 
 218         if (lcs instanceof JIDLLocalCRDImpl) {
 219             JIDLLocalCRDImpl jlcs = (JIDLLocalCRDImpl)lcs ;
 220             byte[] oid = jlcs.getObjectId() ;
 221             servants.deleteServant(oid);
 222             jlcs.unexport() ;
 223         } else {
 224             throw new RuntimeException(
 225                 "TOAImpl.disconnect can not be called on " + lcs ) ;
 226         }
 227     }
 228 }