ORBInitInfoImpl.java revision 608:7e06bf1dcb09
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
26package com.sun.corba.se.impl.interceptors;
27
28import org.omg.CORBA.BAD_PARAM;
29import org.omg.CORBA.BAD_INV_ORDER;
30import org.omg.CORBA.CompletionStatus;
31import org.omg.CORBA.NO_IMPLEMENT;
32import org.omg.CORBA.OBJECT_NOT_EXIST;
33import org.omg.CORBA.LocalObject;
34import org.omg.CORBA.Policy;
35import org.omg.CORBA.PolicyError;
36import org.omg.IOP.CodecFactory;
37import org.omg.PortableInterceptor.ORBInitInfo;
38import org.omg.PortableInterceptor.ClientRequestInterceptor;
39import org.omg.PortableInterceptor.IORInterceptor;
40import org.omg.PortableInterceptor.PolicyFactory;
41import org.omg.PortableInterceptor.ServerRequestInterceptor;
42import org.omg.PortableInterceptor.ORBInitInfoPackage.DuplicateName;
43import org.omg.PortableInterceptor.ORBInitInfoPackage.InvalidName;
44
45import com.sun.corba.se.spi.orb.ORB;
46import com.sun.corba.se.spi.legacy.interceptor.ORBInitInfoExt ;
47import com.sun.corba.se.spi.logging.CORBALogDomains;
48
49import com.sun.corba.se.impl.orbutil.ORBUtility;
50
51import com.sun.corba.se.impl.logging.InterceptorsSystemException;
52import com.sun.corba.se.impl.logging.ORBUtilSystemException;
53import 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 */
59public 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}
382