1 /*
   2  * Copyright (c) 2000, 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.interceptors;
  27 
  28 import org.omg.CORBA.BAD_PARAM;
  29 import org.omg.CORBA.BAD_INV_ORDER;
  30 import org.omg.CORBA.CompletionStatus;
  31 import org.omg.CORBA.NO_IMPLEMENT;
  32 import org.omg.CORBA.OBJECT_NOT_EXIST;
  33 import org.omg.CORBA.LocalObject;
  34 import org.omg.CORBA.Policy;
  35 import org.omg.CORBA.PolicyError;
  36 import org.omg.IOP.CodecFactory;
  37 import org.omg.PortableInterceptor.ORBInitInfo;
  38 import org.omg.PortableInterceptor.ClientRequestInterceptor;
  39 import org.omg.PortableInterceptor.IORInterceptor;
  40 import org.omg.PortableInterceptor.PolicyFactory;
  41 import org.omg.PortableInterceptor.ServerRequestInterceptor;
  42 import org.omg.PortableInterceptor.ORBInitInfoPackage.DuplicateName;
  43 import org.omg.PortableInterceptor.ORBInitInfoPackage.InvalidName;
  44 
  45 import com.sun.corba.se.spi.orb.ORB;
  46 import com.sun.corba.se.spi.legacy.interceptor.ORBInitInfoExt ;
  47 import com.sun.corba.se.spi.logging.CORBALogDomains;
  48 
  49 import com.sun.corba.se.impl.orbutil.ORBUtility;
  50 
  51 import com.sun.corba.se.impl.logging.InterceptorsSystemException;
  52 import com.sun.corba.se.impl.logging.ORBUtilSystemException;
  53 import com.sun.corba.se.impl.logging.OMGSystemException;
  54 
  55 /**
  56  * ORBInitInfoImpl is the implementation of the ORBInitInfo class to be
  57  * passed to ORBInitializers, as described in orbos/99-12-02.
  58  */
  59 public final class ORBInitInfoImpl
  60     extends org.omg.CORBA.LocalObject
  61     implements ORBInitInfo, ORBInitInfoExt
  62 {
  63     // The ORB we are initializing
  64     private ORB orb;
  65 
  66     private InterceptorsSystemException wrapper ;
  67     private ORBUtilSystemException orbutilWrapper ;
  68     private OMGSystemException omgWrapper ;
  69 
  70     // The arguments passed to ORB_init
  71     private String[] args;
  72 
  73     // The ID of the ORB being initialized
  74     private String orbId;
  75 
  76     // The CodecFactory
  77     private CodecFactory codecFactory;
  78 
  79     // The current stage of initialization
  80     private int stage = STAGE_PRE_INIT;
  81 
  82     // The pre-initialization stage (pre_init() being called)
  83     public static final int STAGE_PRE_INIT = 0;
  84 
  85     // The post-initialization stage (post_init() being called)
  86     public static final int STAGE_POST_INIT = 1;
  87 
  88     // Reject all calls - this object should no longer be around.
  89     public static final int STAGE_CLOSED = 2;
  90 
  91     // The description for the OBJECT_NOT_EXIST exception in STAGE_CLOSED
  92     private static final String MESSAGE_ORBINITINFO_INVALID =
  93         "ORBInitInfo object is only valid during ORB_init";
  94 
  95     /**
  96      * Creates a new ORBInitInfoImpl object (scoped to package)
  97      *
  98      * @param args The arguments passed to ORB_init.
  99      */
 100     ORBInitInfoImpl( ORB orb, String[] args,
 101         String orbId, CodecFactory codecFactory )
 102     {
 103         this.orb = orb;
 104 
 105         wrapper = InterceptorsSystemException.get( orb,
 106             CORBALogDomains.RPC_PROTOCOL ) ;
 107         orbutilWrapper = ORBUtilSystemException.get( orb,
 108             CORBALogDomains.RPC_PROTOCOL ) ;
 109         omgWrapper = OMGSystemException.get( orb,
 110             CORBALogDomains.RPC_PROTOCOL ) ;
 111 
 112         this.args = args;
 113         this.orbId = orbId;
 114         this.codecFactory = codecFactory;
 115     }
 116 
 117     /** Return the ORB behind this ORBInitInfo.  This is defined in the
 118      * ORBInitInfoExt interface.
 119      */
 120     public ORB getORB()
 121     {
 122         return orb ;
 123     }
 124 
 125     /**
 126      * Sets the current stage we are in.  This limits access to certain
 127      * functionality.
 128      */
 129     void setStage( int stage ) {
 130         this.stage = stage;
 131     }
 132 
 133     /**
 134      * Throws an exception if the current stage is STAGE_CLOSED.
 135      * This is called before any method is invoked to ensure that
 136      * no method invocations are attempted after all calls to post_init()
 137      * are completed.
 138      */
 139     private void checkStage() {
 140         if( stage == STAGE_CLOSED ) {
 141             throw wrapper.orbinitinfoInvalid() ;
 142         }
 143     }
 144 
 145     /*
 146      *******************************************************************
 147      * The following are implementations of the ORBInitInfo operations.
 148      *******************************************************************/
 149 
 150     /**
 151      * This attribute contains the arguments passed to ORB_init.  They may
 152      * or may not contain the ORB's arguments
 153      */
 154     public String[] arguments () {
 155         checkStage();
 156         return args;
 157     }
 158 
 159     /**
 160      * This attribute is the ID of the ORB being initialized
 161      */
 162     public String orb_id () {
 163         checkStage();
 164         return orbId;
 165     }
 166 
 167     /**
 168      * This attribute is the IOP::CodecFactory.  The CodecFactory is normally
 169      * obtained via a call to ORB::resolve_initial_references( "CodecFactory" )
 170      * but since the ORB is not yet available and Interceptors, particularly
 171      * when processing service contexts, will require a Codec, a means of
 172      * obtaining a Codec is necessary during ORB intialization.
 173      */
 174     public CodecFactory codec_factory () {
 175         checkStage();
 176         return codecFactory;
 177     }
 178 
 179     /**
 180      * See orbos/99-12-02, Chapter 11, Dynamic Initial References on page
 181      * 11-81.  This operation is identical to ORB::register_initial_reference
 182      * described there.  This same functionality exists here because the ORB,
 183      * not yet fully initialized, is not yet available but initial references
 184      * may need to be registered as part of Interceptor registration.
 185      * <p>
 186      * This method may not be called during post_init.
 187      */
 188     public void register_initial_reference( String id,
 189                                             org.omg.CORBA.Object obj )
 190         throws InvalidName
 191     {
 192         checkStage();
 193         if( id == null ) nullParam();
 194 
 195         // As per CORBA 3.0 section 21.8.1,
 196         // if null is passed as the obj parameter,
 197         // throw BAD_PARAM with minor code OMGSystemException.RIR_WITH_NULL_OBJECT.
 198         // Though the spec is talking about IDL null, we will address both
 199         // Java null and IDL null:
 200         // Note: Local Objects can never be nil!
 201         if( obj == null ) {
 202             throw omgWrapper.rirWithNullObject() ;
 203         }
 204 
 205         // This check was made to determine that the objref is a
 206         // non-local objref that is fully
 207         // initialized: this was called only for its side-effects of
 208         // possibly throwing exceptions.  However, registering
 209         // local objects should be permitted!
 210         // XXX/Revisit?
 211         // IOR ior = ORBUtility.getIOR( obj ) ;
 212 
 213         // Delegate to ORB.  If ORB version throws InvalidName, convert to
 214         // equivalent Portable Interceptors InvalidName.
 215         try {
 216             orb.register_initial_reference( id, obj );
 217         } catch( org.omg.CORBA.ORBPackage.InvalidName e ) {
 218             InvalidName exc = new InvalidName( e.getMessage() );
 219             exc.initCause( e ) ;
 220             throw exc ;
 221         }
 222     }
 223 
 224     /**
 225      * This operation is only valid during post_init.  It is identical to
 226      * ORB::resolve_initial_references.  This same functionality exists here
 227      * because the ORB, not yet fully initialized, is not yet available,
 228      * but initial references may be required from the ORB as part
 229      * of Interceptor registration.
 230      * <p>
 231      * (incorporates changes from errata in orbos/00-01-01)
 232      * <p>
 233      * This method may not be called during pre_init.
 234      */
 235     public org.omg.CORBA.Object resolve_initial_references (String id)
 236         throws InvalidName
 237     {
 238         checkStage();
 239         if( id == null ) nullParam();
 240 
 241         if( stage == STAGE_PRE_INIT ) {
 242             // Initializer is not allowed to invoke this method during
 243             // this stage.
 244 
 245             // _REVISIT_ Spec issue: What exception should really be
 246             // thrown here?
 247             throw wrapper.rirInvalidPreInit() ;
 248         }
 249 
 250         org.omg.CORBA.Object objRef = null;
 251 
 252         try {
 253             objRef = orb.resolve_initial_references( id );
 254         }
 255         catch( org.omg.CORBA.ORBPackage.InvalidName e ) {
 256             // Convert PIDL to IDL exception:
 257             throw new InvalidName();
 258         }
 259 
 260         return objRef;
 261     }
 262 
 263     // New method from CORBA 3.1
 264     public void add_client_request_interceptor_with_policy (
 265         ClientRequestInterceptor interceptor, Policy[] policies )
 266         throws DuplicateName
 267     {
 268         // XXX ignore policies for now
 269         add_client_request_interceptor( interceptor ) ;
 270     }
 271 
 272     /**
 273      * This operation is used to add a client-side request Interceptor to
 274      * the list of client-side request Interceptors.
 275      * <p>
 276      * If a client-side request Interceptor has already been registered
 277      * with this Interceptor's name, DuplicateName is raised.
 278      */
 279     public void add_client_request_interceptor (
 280         ClientRequestInterceptor interceptor)
 281         throws DuplicateName
 282     {
 283         checkStage();
 284         if( interceptor == null ) nullParam();
 285 
 286         orb.getPIHandler().register_interceptor( interceptor,
 287             InterceptorList.INTERCEPTOR_TYPE_CLIENT );
 288     }
 289 
 290     // New method from CORBA 3.1
 291     public void add_server_request_interceptor_with_policy (
 292         ServerRequestInterceptor interceptor, Policy[] policies )
 293         throws DuplicateName, PolicyError
 294     {
 295         // XXX ignore policies for now
 296         add_server_request_interceptor( interceptor ) ;
 297     }
 298 
 299     /**
 300      * This operation is used to add a server-side request Interceptor to
 301      * the list of server-side request Interceptors.
 302      * <p>
 303      * If a server-side request Interceptor has already been registered
 304      * with this Interceptor's name, DuplicateName is raised.
 305      */
 306     public void add_server_request_interceptor (
 307         ServerRequestInterceptor interceptor)
 308         throws DuplicateName
 309     {
 310         checkStage();
 311         if( interceptor == null ) nullParam();
 312 
 313         orb.getPIHandler().register_interceptor( interceptor,
 314             InterceptorList.INTERCEPTOR_TYPE_SERVER );
 315     }
 316 
 317     // New method from CORBA 3.1
 318     public void add_ior_interceptor_with_policy (
 319         IORInterceptor interceptor, Policy[] policies )
 320         throws DuplicateName, PolicyError
 321     {
 322         // XXX ignore policies for now
 323         add_ior_interceptor( interceptor ) ;
 324     }
 325 
 326     /**
 327      * This operation is used to add an IOR Interceptor to
 328      * the list of IOR Interceptors.
 329      * <p>
 330      * If an IOR Interceptor has already been registered
 331      * with this Interceptor's name, DuplicateName is raised.
 332      */
 333     public void add_ior_interceptor (
 334         IORInterceptor interceptor )
 335         throws DuplicateName
 336     {
 337         checkStage();
 338         if( interceptor == null ) nullParam();
 339 
 340         orb.getPIHandler().register_interceptor( interceptor,
 341             InterceptorList.INTERCEPTOR_TYPE_IOR );
 342     }
 343 
 344     /**
 345      * A service calls allocate_slot_id to allocate a slot on
 346      * PortableInterceptor::Current.
 347      *
 348      * @return The index to the slot which has been allocated.
 349      */
 350     public int allocate_slot_id () {
 351         checkStage();
 352 
 353         return ((PICurrent)orb.getPIHandler().getPICurrent()).allocateSlotId( );
 354 
 355     }
 356 
 357     /**
 358      * Register a PolicyFactory for the given PolicyType.
 359      * <p>
 360      * If a PolicyFactory already exists for the given PolicyType,
 361      * BAD_INV_ORDER is raised with a minor code of TBD_BIO+2.
 362      */
 363     public void register_policy_factory( int type,
 364                                          PolicyFactory policy_factory )
 365     {
 366         checkStage();
 367         if( policy_factory == null ) nullParam();
 368         orb.getPIHandler().registerPolicyFactory( type, policy_factory );
 369     }
 370 
 371 
 372     /**
 373      * Called when an invalid null parameter was passed.  Throws a
 374      * BAD_PARAM with a minor code of 1
 375      */
 376     private void nullParam()
 377         throws BAD_PARAM
 378     {
 379         throw orbutilWrapper.nullParam() ;
 380     }
 381 }