ORBImpl.java revision 667:d0315150c39d
1/*
2 * Copyright (c) 2002, 2015, 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.orb;
27
28import java.applet.Applet;
29
30import java.io.IOException;
31
32import java.lang.reflect.Constructor;
33import java.lang.reflect.Field;
34import java.lang.reflect.Modifier;
35import java.lang.reflect.InvocationTargetException;
36
37import java.util.Set;
38import java.util.HashSet;
39import java.util.ArrayList;
40import java.util.Iterator;
41import java.util.Properties;
42import java.util.Vector;
43import java.util.Hashtable;
44import java.util.Map;
45import java.util.HashMap;
46import java.util.LinkedList;
47import java.util.Collection;
48import java.util.Collections;
49import java.util.StringTokenizer;
50import java.util.Enumeration;
51import java.util.WeakHashMap;
52
53import java.net.InetAddress;
54
55import java.security.PrivilegedAction;
56import java.security.AccessController;
57
58import javax.rmi.CORBA.Util;
59import javax.rmi.CORBA.ValueHandler;
60
61import org.omg.CORBA.Context;
62import org.omg.CORBA.ContextList;
63import org.omg.CORBA.Environment;
64import org.omg.CORBA.ExceptionList;
65import org.omg.CORBA.ORBPackage.InvalidName;
66import org.omg.CORBA.NVList;
67import org.omg.CORBA.TCKind;
68import org.omg.CORBA.NamedValue;
69import org.omg.CORBA.Request;
70import org.omg.CORBA.SystemException;
71import org.omg.CORBA.CompletionStatus;
72import org.omg.CORBA.TypeCode;
73import org.omg.CORBA.Any;
74import org.omg.CORBA.StructMember;
75import org.omg.CORBA.UnionMember;
76import org.omg.CORBA.ValueMember;
77import org.omg.CORBA.BAD_PARAM;
78import org.omg.CORBA.MARSHAL;
79
80import org.omg.CORBA.portable.ValueFactory;
81
82import org.omg.CORBA.ORBPackage.InvalidName;
83
84import com.sun.org.omg.SendingContext.CodeBase;
85
86import com.sun.corba.se.pept.broker.Broker;
87import com.sun.corba.se.pept.protocol.ClientInvocationInfo;
88import com.sun.corba.se.pept.transport.ContactInfo;
89import com.sun.corba.se.pept.transport.ConnectionCache;
90import com.sun.corba.se.pept.transport.TransportManager;
91
92import com.sun.corba.se.spi.ior.IOR;
93import com.sun.corba.se.spi.ior.IdentifiableFactoryFinder;
94import com.sun.corba.se.spi.ior.TaggedComponentFactoryFinder;
95import com.sun.corba.se.spi.ior.IORFactories;
96import com.sun.corba.se.spi.ior.ObjectKey;
97import com.sun.corba.se.spi.ior.ObjectKeyFactory;
98import com.sun.corba.se.spi.ior.iiop.IIOPFactories;
99import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
100import com.sun.corba.se.spi.oa.OAInvocationInfo;
101import com.sun.corba.se.spi.oa.ObjectAdapterFactory;
102import com.sun.corba.se.spi.orb.DataCollector;
103import com.sun.corba.se.spi.orb.Operation;
104import com.sun.corba.se.spi.orb.ORBData;
105import com.sun.corba.se.spi.orb.ORBConfigurator;
106import com.sun.corba.se.spi.orb.ParserImplBase;
107import com.sun.corba.se.spi.orb.PropertyParser;
108import com.sun.corba.se.spi.orb.OperationFactory;
109import com.sun.corba.se.spi.orb.ORBVersion;
110import com.sun.corba.se.spi.orb.ORBVersionFactory;
111import com.sun.corba.se.spi.orbutil.closure.ClosureFactory;
112import com.sun.corba.se.spi.orbutil.threadpool.ThreadPoolManager;
113import com.sun.corba.se.spi.protocol.ClientDelegateFactory;
114import com.sun.corba.se.spi.protocol.RequestDispatcherRegistry;
115import com.sun.corba.se.spi.protocol.CorbaServerRequestDispatcher;
116import com.sun.corba.se.spi.protocol.RequestDispatcherDefault;
117import com.sun.corba.se.spi.protocol.PIHandler;
118import com.sun.corba.se.spi.protocol.CorbaMessageMediator;
119import com.sun.corba.se.spi.protocol.ForwardException;
120import com.sun.corba.se.spi.resolver.Resolver;
121import com.sun.corba.se.spi.resolver.LocalResolver;
122import com.sun.corba.se.spi.orb.StringPair;
123import com.sun.corba.se.spi.orb.StringPair;
124import com.sun.corba.se.spi.transport.CorbaContactInfoListFactory;
125import com.sun.corba.se.spi.transport.CorbaTransportManager;
126import com.sun.corba.se.spi.legacy.connection.LegacyServerSocketManager;
127import com.sun.corba.se.spi.copyobject.CopierManager;
128import com.sun.corba.se.spi.presentation.rmi.PresentationDefaults;
129import com.sun.corba.se.spi.presentation.rmi.PresentationManager;
130import com.sun.corba.se.spi.presentation.rmi.StubAdapter;
131import com.sun.corba.se.spi.servicecontext.ServiceContextRegistry;
132
133import com.sun.corba.se.impl.corba.TypeCodeFactory;
134import com.sun.corba.se.impl.corba.TypeCodeImpl;
135import com.sun.corba.se.impl.corba.NVListImpl;
136import com.sun.corba.se.impl.corba.ExceptionListImpl;
137import com.sun.corba.se.impl.corba.ContextListImpl;
138import com.sun.corba.se.impl.corba.NamedValueImpl;
139import com.sun.corba.se.impl.corba.EnvironmentImpl;
140import com.sun.corba.se.impl.corba.AsynchInvoke;
141import com.sun.corba.se.impl.corba.AnyImpl;
142import com.sun.corba.se.impl.corba.RequestImpl;
143import com.sun.corba.se.impl.dynamicany.DynAnyFactoryImpl;
144import com.sun.corba.se.impl.encoding.EncapsOutputStream;
145import com.sun.corba.se.impl.encoding.CachedCodeBase;
146import com.sun.corba.se.impl.interceptors.PIHandlerImpl;
147import com.sun.corba.se.impl.interceptors.PINoOpHandlerImpl;
148import com.sun.corba.se.impl.ior.TaggedComponentFactoryFinderImpl;
149import com.sun.corba.se.impl.ior.TaggedProfileFactoryFinderImpl;
150import com.sun.corba.se.impl.ior.TaggedProfileTemplateFactoryFinderImpl;
151import com.sun.corba.se.impl.oa.toa.TOAFactory;
152import com.sun.corba.se.impl.oa.poa.BadServerIdHandler;
153import com.sun.corba.se.impl.oa.poa.DelegateImpl;
154import com.sun.corba.se.impl.oa.poa.POAFactory;
155import com.sun.corba.se.impl.orbutil.ORBConstants;
156import com.sun.corba.se.impl.orbutil.ORBUtility;
157import com.sun.corba.se.impl.orbutil.StackImpl;
158import com.sun.corba.se.impl.orbutil.threadpool.ThreadPoolImpl;
159import com.sun.corba.se.impl.orbutil.threadpool.ThreadPoolManagerImpl;
160import com.sun.corba.se.impl.protocol.RequestDispatcherRegistryImpl;
161import com.sun.corba.se.impl.protocol.CorbaInvocationInfo;
162import com.sun.corba.se.impl.transport.CorbaTransportManagerImpl;
163import com.sun.corba.se.impl.legacy.connection.LegacyServerSocketManagerImpl;
164import com.sun.corba.se.impl.util.Utility;
165import com.sun.corba.se.impl.logging.ORBUtilSystemException;
166import com.sun.corba.se.impl.copyobject.CopierManagerImpl;
167import com.sun.corba.se.impl.presentation.rmi.PresentationManagerImpl;
168import com.sun.corba.se.impl.transport.ManagedLocalsThread;
169
170/**
171 * The JavaIDL ORB implementation.
172 */
173public class ORBImpl extends com.sun.corba.se.spi.orb.ORB
174{
175    protected TransportManager transportManager;
176    protected LegacyServerSocketManager legacyServerSocketManager;
177
178    private ThreadLocal OAInvocationInfoStack ;
179
180    private ThreadLocal clientInvocationInfoStack ;
181
182    // pure java orb, caching the servant IOR per ORB
183    private static IOR codeBaseIOR ;
184
185    // Vector holding deferred Requests
186    private Vector            dynamicRequests ;
187    private SynchVariable     svResponseReceived ;
188
189    private java.lang.Object runObj = new java.lang.Object();
190    private java.lang.Object shutdownObj = new java.lang.Object();
191    private java.lang.Object waitForCompletionObj = new java.lang.Object();
192    private static final byte STATUS_OPERATING = 1;
193    private static final byte STATUS_SHUTTING_DOWN = 2;
194    private static final byte STATUS_SHUTDOWN = 3;
195    private static final byte STATUS_DESTROYED = 4;
196    private byte status = STATUS_OPERATING;
197
198    // XXX Should we move invocation tracking to the first level server dispatcher?
199    private java.lang.Object invocationObj = new java.lang.Object();
200    private int numInvocations = 0;
201
202    // thread local variable to store a boolean to detect deadlock in
203    // ORB.shutdown(true).
204    private ThreadLocal isProcessingInvocation = new ThreadLocal () {
205        protected java.lang.Object initialValue() {
206            return Boolean.FALSE;
207        }
208    };
209
210    // This map is caching TypeCodes created for a certain class (key)
211    // and is used in Util.writeAny()
212    private Map typeCodeForClassMap ;
213
214    // Cache to hold ValueFactories (Helper classes) keyed on repository ids
215    private Hashtable valueFactoryCache = new Hashtable();
216
217    // thread local variable to store the current ORB version.
218    // default ORB version is the version of ORB with correct Rep-id
219    // changes
220    private ThreadLocal orbVersionThreadLocal ;
221
222    private RequestDispatcherRegistry requestDispatcherRegistry ;
223
224    private CopierManager copierManager ;
225
226    private int transientServerId ;
227
228    private ServiceContextRegistry serviceContextRegistry ;
229
230    // Needed here to implement connect/disconnect
231    private TOAFactory toaFactory ;
232
233    // Needed here for set_delegate
234    private POAFactory poaFactory ;
235
236    // The interceptor handler, which provides portable interceptor services for
237    // subcontracts and object adapters.
238    private PIHandler pihandler ;
239
240    private ORBData configData ;
241
242    private BadServerIdHandler badServerIdHandler ;
243
244    private ClientDelegateFactory clientDelegateFactory ;
245
246    private CorbaContactInfoListFactory corbaContactInfoListFactory ;
247
248    // All access to resolver, localResolver, and urlOperation must be protected using
249    // resolverLock.  Do not hold the ORBImpl lock while accessing
250    // resolver, or deadlocks may occur.
251    // Note that we now have separate locks for each resolver type.  This is due
252    // to bug 6980681 and 6238477, which was caused by a deadlock while resolving a
253    // corbaname: URL that contained a reference to the same ORB as the
254    // ORB making the call to string_to_object.  This caused a deadlock between the
255    // client thread holding the single lock for access to the urlOperation,
256    // and the server thread handling the client is_a request waiting on the
257    // same lock to access the localResolver.
258
259
260    // Used for resolver_initial_references and list_initial_services
261    private Resolver resolver ;
262
263    // Used for register_initial_references
264    private LocalResolver localResolver ;
265
266    // Converts strings to object references for resolvers and string_to_object
267    private Operation urlOperation ;
268    private final Object urlOperationLock = new java.lang.Object() ;
269
270    private CorbaServerRequestDispatcher insNamingDelegate ;
271
272    // resolverLock must be used for all access to either resolver or
273    // localResolver, since it is possible for the resolver to indirectly
274    // refer to the localResolver.  Also used to protect access to
275    // insNamingDelegate.
276    private final Object resolverLock = new Object() ;
277
278    private TaggedComponentFactoryFinder taggedComponentFactoryFinder ;
279
280    private IdentifiableFactoryFinder taggedProfileFactoryFinder ;
281
282    private IdentifiableFactoryFinder taggedProfileTemplateFactoryFinder ;
283
284    private ObjectKeyFactory objectKeyFactory ;
285
286    private boolean orbOwnsThreadPoolManager = false ;
287
288    private ThreadPoolManager threadpoolMgr;
289
290    private void dprint( String msg )
291    {
292        ORBUtility.dprint( this, msg ) ;
293    }
294
295    ////////////////////////////////////////////////////
296    //
297    // NOTE:
298    //
299    // Methods that are synchronized MUST stay synchronized.
300    //
301    // Methods that are NOT synchronized must stay that way to avoid deadlock.
302    //
303    //
304    // REVISIT:
305    //
306    // checkShutDownState - lock on different object - and normalize usage.
307    // starting/FinishDispatch and Shutdown
308    //
309
310    public ORBData getORBData()
311    {
312        return configData ;
313    }
314
315    public PIHandler getPIHandler()
316    {
317        return pihandler ;
318    }
319
320    /**
321     * Create a new ORB. Should be followed by the appropriate
322     * set_parameters() call.
323     */
324    public ORBImpl()
325    {
326        // All initialization is done through set_parameters().
327    }
328
329    public ORBVersion getORBVersion()
330    {
331        synchronized (this) {
332                checkShutdownState();
333        }
334        return (ORBVersion)(orbVersionThreadLocal.get()) ;
335    }
336
337    public void setORBVersion(ORBVersion verObj)
338    {
339        synchronized (this) {
340                checkShutdownState();
341        }
342        orbVersionThreadLocal.set(verObj);
343    }
344
345/****************************************************************************
346 * The following methods are ORB initialization
347 ****************************************************************************/
348
349    // preInit initializes all non-pluggable ORB data that is independent
350    // of the property parsing.
351    private void preInit( String[] params, Properties props )
352    {
353        // Before ORBConfiguration we need to set a PINoOpHandlerImpl,
354        // because PersisentServer Initialization inside configurator will
355        // invoke orb.resolve_initial_references( ) which will result in a
356        // check on piHandler to invoke Interceptors. We do not want any
357        // Interceptors to be invoked before the complete ORB initialization.
358        // piHandler will be replaced by a real PIHandler implementation at the
359        // end of this method.
360        pihandler = new PINoOpHandlerImpl( );
361
362        // This is the unique id of this server (JVM). Multiple incarnations
363        // of this server will get different ids.
364        // Compute transientServerId = milliseconds since Jan 1, 1970
365        // Note: transientServerId will wrap in about 2^32 / 86400000 = 49.7 days.
366        // If two ORBS are started at the same time then there is a possibility
367        // of having the same transientServerId. This may result in collision
368        // and may be a problem in ior.isLocal() check to see if the object
369        // belongs to the current ORB. This problem is taken care of by checking
370        // to see if the IOR port matches ORB server port in legacyIsLocalServerPort()
371        // method.
372        //
373        // XXX need to move server ID to a string for CORBA 3.0.  At that point,
374        // make this more unique (possibly use java.rmi.server.UID).
375        transientServerId = (int)System.currentTimeMillis();
376
377        orbVersionThreadLocal  = new ThreadLocal () {
378            protected java.lang.Object initialValue() {
379                // set default to version of the ORB with correct Rep-ids
380                return ORBVersionFactory.getORBVersion() ;
381            }
382        };
383
384
385        requestDispatcherRegistry = new RequestDispatcherRegistryImpl(
386            this, ORBConstants.DEFAULT_SCID);
387        copierManager = new CopierManagerImpl( this ) ;
388
389        taggedComponentFactoryFinder =
390            new TaggedComponentFactoryFinderImpl(this) ;
391        taggedProfileFactoryFinder =
392            new TaggedProfileFactoryFinderImpl(this) ;
393        taggedProfileTemplateFactoryFinder =
394            new TaggedProfileTemplateFactoryFinderImpl(this) ;
395
396        dynamicRequests = new Vector();
397        svResponseReceived = new SynchVariable();
398
399        OAInvocationInfoStack =
400            new ThreadLocal () {
401                protected java.lang.Object initialValue()
402                {
403                    return new StackImpl();
404                }
405            };
406
407        clientInvocationInfoStack =
408            new ThreadLocal() {
409                protected java.lang.Object initialValue() {
410                    return new StackImpl();
411                }
412            };
413
414        serviceContextRegistry = new ServiceContextRegistry( this ) ;
415    }
416
417    protected void setDebugFlags( String[] args )
418    {
419        for (int ctr=0; ctr<args.length; ctr++ ) {
420            String token = args[ctr] ;
421
422            // If there is a public boolean data member in this class
423            // named token + "DebugFlag", set it to true.
424            try {
425                Field fld = this.getClass().getField( token + "DebugFlag" ) ;
426                int mod = fld.getModifiers() ;
427                if (Modifier.isPublic( mod ) && !Modifier.isStatic( mod ))
428                    if (fld.getType() == boolean.class)
429                        fld.setBoolean( this, true ) ;
430            } catch (Exception exc) {
431                // ignore it XXX log this as info
432            }
433        }
434    }
435
436    // Class that defines a parser that gets the name of the
437    // ORBConfigurator class.
438    private static class ConfigParser extends ParserImplBase {
439        // The default here is the ORBConfiguratorImpl that we define,
440        // but this can be replaced.
441        public Class configurator = ORBConfiguratorImpl.class ;
442
443        public PropertyParser makeParser()
444        {
445            PropertyParser parser = new PropertyParser() ;
446            parser.add( ORBConstants.SUN_PREFIX + "ORBConfigurator",
447                OperationFactory.classAction(), "configurator" ) ;
448            return parser ;
449        }
450    }
451
452    private void postInit( String[] params, DataCollector dataCollector )
453    {
454        // First, create the standard ORB config data.
455        // This must be initialized before the ORBConfigurator
456        // is executed.
457        configData = new ORBDataParserImpl( this, dataCollector) ;
458
459        // Set the debug flags early so they can be used by other
460        // parts of the initialization.
461        setDebugFlags( configData.getORBDebugFlags() ) ;
462
463        // REVISIT: this should go away after more transport init cleanup
464        // and going to ORT based ORBD.
465        getTransportManager();
466        getLegacyServerSocketManager();
467
468        // Create a parser to get the configured ORBConfigurator.
469        ConfigParser parser = new ConfigParser() ;
470        parser.init( dataCollector ) ;
471
472        ORBConfigurator configurator =  null ;
473        try {
474            configurator =
475                (ORBConfigurator)(parser.configurator.newInstance()) ;
476        } catch (Exception iexc) {
477            throw wrapper.badOrbConfigurator( iexc, parser.configurator.getName() ) ;
478        }
479
480        // Finally, run the configurator.  Note that the default implementation allows
481        // other configurators with their own parsers to run,
482        // using the same DataCollector.
483        try {
484            configurator.configure( dataCollector, this ) ;
485        } catch (Exception exc) {
486            throw wrapper.orbConfiguratorError( exc ) ;
487        }
488
489        // Last of all, create the PIHandler and run the ORB initializers.
490        pihandler = new PIHandlerImpl( this, params) ;
491        pihandler.initialize() ;
492
493        // Initialize the thread manager pool and byte buffer pool
494        // so they may be initialized & accessed without synchronization
495        getThreadPoolManager();
496
497        super.getByteBufferPool();
498    }
499
500    private synchronized POAFactory getPOAFactory()
501    {
502        if (poaFactory == null) {
503            poaFactory = (POAFactory)requestDispatcherRegistry.getObjectAdapterFactory(
504                ORBConstants.TRANSIENT_SCID ) ;
505        }
506
507        return poaFactory ;
508    }
509
510    private synchronized TOAFactory getTOAFactory()
511    {
512        if (toaFactory == null) {
513            toaFactory = (TOAFactory)requestDispatcherRegistry.getObjectAdapterFactory(
514                ORBConstants.TOA_SCID ) ;
515        }
516
517        return toaFactory ;
518    }
519
520    public void set_parameters( Properties props )
521    {
522        synchronized (this) {
523                checkShutdownState();
524        }
525        preInit( null, props ) ;
526        DataCollector dataCollector =
527            DataCollectorFactory.create( props, getLocalHostName() ) ;
528        postInit( null, dataCollector ) ;
529    }
530
531    protected void set_parameters(Applet app, Properties props)
532    {
533        preInit( null, props ) ;
534        DataCollector dataCollector =
535            DataCollectorFactory.create( app, props, getLocalHostName() ) ;
536        postInit( null, dataCollector ) ;
537    }
538
539    protected void set_parameters (String[] params, Properties props)
540    {
541        preInit( params, props ) ;
542        DataCollector dataCollector =
543            DataCollectorFactory.create( params, props, getLocalHostName() ) ;
544        postInit( params, dataCollector ) ;
545    }
546
547/****************************************************************************
548 * The following methods are standard public CORBA ORB APIs
549 ****************************************************************************/
550
551    public synchronized org.omg.CORBA.portable.OutputStream create_output_stream()
552    {
553        checkShutdownState();
554        return sun.corba.OutputStreamFactory.newEncapsOutputStream(this);
555    }
556
557    /**
558     * Get a Current pseudo-object.
559     * The Current interface is used to manage thread-specific
560     * information for use by the transactions, security and other
561     * services. This method is deprecated,
562     * and replaced by ORB.resolve_initial_references("NameOfCurrentObject");
563     *
564     * @return          a Current pseudo-object.
565     * @deprecated
566     */
567    public synchronized org.omg.CORBA.Current get_current()
568    {
569        checkShutdownState();
570
571        /* _REVISIT_
572           The implementation of get_current is not clear. How would
573           ORB know whether the caller wants a Current for transactions
574           or security ?? Or is it assumed that there is just one
575           implementation for both ? If Current is thread-specific,
576           then it should not be instantiated; so where does the
577           ORB get a Current ?
578
579           This should probably be deprecated. */
580
581        throw wrapper.genericNoImpl() ;
582    }
583
584    /**
585     * Create an NVList
586     *
587     * @param count     size of list to create
588     * @result          NVList created
589     *
590     * @see NVList
591     */
592    public synchronized NVList create_list(int count)
593    {
594        checkShutdownState();
595        return new NVListImpl(this, count);
596    }
597
598    /**
599     * Create an NVList corresponding to an OperationDef
600     *
601     * @param oper      operation def to use to create list
602     * @result          NVList created
603     *
604     * @see NVList
605     */
606    public synchronized NVList create_operation_list(org.omg.CORBA.Object oper)
607    {
608        checkShutdownState();
609        throw wrapper.genericNoImpl() ;
610    }
611
612    /**
613     * Create a NamedValue
614     *
615     * @result          NamedValue created
616     */
617    public synchronized NamedValue create_named_value(String s, Any any, int flags)
618    {
619        checkShutdownState();
620        return new NamedValueImpl(this, s, any, flags);
621    }
622
623    /**
624     * Create an ExceptionList
625     *
626     * @result          ExceptionList created
627     */
628    public synchronized org.omg.CORBA.ExceptionList create_exception_list()
629    {
630        checkShutdownState();
631        return new ExceptionListImpl();
632    }
633
634    /**
635     * Create a ContextList
636     *
637     * @result          ContextList created
638     */
639    public synchronized org.omg.CORBA.ContextList create_context_list()
640    {
641        checkShutdownState();
642        return new ContextListImpl(this);
643    }
644
645    /**
646     * Get the default Context object
647     *
648     * @result          the default Context object
649     */
650    public synchronized org.omg.CORBA.Context get_default_context()
651    {
652        checkShutdownState();
653        throw wrapper.genericNoImpl() ;
654    }
655
656    /**
657     * Create an Environment
658     *
659     * @result          Environment created
660     */
661    public synchronized org.omg.CORBA.Environment create_environment()
662    {
663        checkShutdownState();
664        return new EnvironmentImpl();
665    }
666
667    public synchronized void send_multiple_requests_oneway(Request[] req)
668    {
669        checkShutdownState();
670
671        // Invoke the send_oneway on each new Request
672        for (int i = 0; i < req.length; i++) {
673            req[i].send_oneway();
674        }
675    }
676
677    /**
678     * Send multiple dynamic requests asynchronously.
679     *
680     * @param req         an array of request objects.
681     */
682    public synchronized void send_multiple_requests_deferred(Request[] req)
683    {
684        checkShutdownState();
685
686        // add the new Requests to pending dynamic Requests
687        for (int i = 0; i < req.length; i++) {
688            dynamicRequests.addElement(req[i]);
689        }
690
691        // Invoke the send_deferred on each new Request
692        for (int i = 0; i < req.length; i++) {
693            AsynchInvoke invokeObject = new AsynchInvoke( this,
694                (com.sun.corba.se.impl.corba.RequestImpl)req[i], true);
695            new ManagedLocalsThread(invokeObject).start();
696        }
697    }
698
699    /**
700     * Find out if any of the deferred invocations have a response yet.
701     */
702    public synchronized boolean poll_next_response()
703    {
704        checkShutdownState();
705
706        Request currRequest;
707
708        // poll on each pending request
709        Enumeration ve = dynamicRequests.elements();
710        while (ve.hasMoreElements() == true) {
711            currRequest = (Request)ve.nextElement();
712            if (currRequest.poll_response() == true) {
713                return true;
714            }
715        }
716        return false;
717    }
718
719    /**
720     * Get the next request that has gotten a response.
721     *
722     * @result            the next request ready with a response.
723     */
724    public org.omg.CORBA.Request get_next_response()
725        throws org.omg.CORBA.WrongTransaction
726    {
727        synchronized( this ) {
728            checkShutdownState();
729        }
730
731        while (true) {
732            // check if there already is a response
733            synchronized ( dynamicRequests ) {
734                Enumeration elems = dynamicRequests.elements();
735                while ( elems.hasMoreElements() ) {
736                    Request currRequest = (Request)elems.nextElement();
737                    if ( currRequest.poll_response() ) {
738                        // get the response for this successfully polled Request
739                        currRequest.get_response();
740                        dynamicRequests.removeElement(currRequest);
741                        return currRequest;
742                    }
743                }
744            }
745
746            // wait for a response
747            synchronized(this.svResponseReceived) {
748                while (!this.svResponseReceived.value()) {
749                    try {
750                        this.svResponseReceived.wait();
751                    } catch(java.lang.InterruptedException ex) {
752                        // NO-OP
753                    }
754                }
755                // reinitialize the response flag
756                this.svResponseReceived.reset();
757            }
758        }
759    }
760
761    /**
762     * Notify response to ORB for get_next_response
763     */
764    public void notifyORB()
765    {
766        synchronized (this) {
767                checkShutdownState();
768        }
769        synchronized (this.svResponseReceived) {
770            this.svResponseReceived.set();
771            this.svResponseReceived.notify();
772        }
773    }
774
775    /**
776     * Convert an object ref to a string.
777     * @param obj The object to stringify.
778     * @return A stringified object reference.
779     */
780    public synchronized String object_to_string(org.omg.CORBA.Object obj)
781    {
782        checkShutdownState();
783
784        // Handle the null objref case
785        if (obj == null) {
786            IOR nullIOR = IORFactories.makeIOR( this ) ;
787            return nullIOR.stringify();
788        }
789
790        IOR ior = null ;
791
792        try {
793            ior = ORBUtility.connectAndGetIOR( this, obj ) ;
794        } catch (BAD_PARAM bp) {
795            // Throw MARSHAL instead if this is a LOCAL_OBJECT_NOT_ALLOWED error.
796            if (bp.minor == ORBUtilSystemException.LOCAL_OBJECT_NOT_ALLOWED) {
797                throw omgWrapper.notAnObjectImpl( bp ) ;
798            } else
799                // Not a local object problem: just rethrow the exception.
800                // Do not wrap and log this, since it was already logged at its
801                // point of origin.
802                throw bp ;
803        }
804
805        return ior.stringify() ;
806    }
807
808    /**
809     * Convert a stringified object reference to the object it represents.
810     * @param str The stringified object reference.
811     * @return The unstringified object reference.
812     */
813    public org.omg.CORBA.Object string_to_object(String str)
814    {
815        Operation op ;
816
817        synchronized (this) {
818            checkShutdownState();
819            op = urlOperation ;
820        }
821
822        if (str == null)
823            throw wrapper.nullParam() ;
824
825        synchronized (urlOperationLock) {
826            org.omg.CORBA.Object obj = (org.omg.CORBA.Object)op.operate( str ) ;
827            return obj ;
828        }
829    }
830
831    // pure java orb support, moved this method from FVDCodeBaseImpl.
832    // Note that we connect this if we have not already done so.
833    public synchronized IOR getFVDCodeBaseIOR()
834    {
835        checkShutdownState();
836
837        if (codeBaseIOR != null) // i.e. We are already connected to it
838            return codeBaseIOR;
839
840        // backward compatability 4365188
841        CodeBase cb;
842
843        ValueHandler vh = ORBUtility.createValueHandler();
844
845        cb = (CodeBase)vh.getRunTimeCodeBase();
846        return ORBUtility.connectAndGetIOR( this, cb ) ;
847    }
848
849    /**
850     * Get the TypeCode for a primitive type.
851     *
852     * @param tcKind    the integer kind for the primitive type
853     * @return          the requested TypeCode
854     */
855    public synchronized TypeCode get_primitive_tc(TCKind tcKind)
856    {
857        checkShutdownState();
858        return get_primitive_tc( tcKind.value() ) ;
859    }
860
861    /**
862     * Create a TypeCode for a structure.
863     *
864     * @param id                the logical id for the typecode.
865     * @param name      the name for the typecode.
866     * @param members   an array describing the members of the TypeCode.
867     * @return          the requested TypeCode.
868     */
869    public synchronized TypeCode create_struct_tc(String id,
870                                     String name,
871                                     StructMember[] members)
872    {
873        checkShutdownState();
874        return new TypeCodeImpl(this, TCKind._tk_struct, id, name, members);
875    }
876
877    /**
878     * Create a TypeCode for a union.
879     *
880     * @param id                the logical id for the typecode.
881     * @param name      the name for the typecode.
882     * @param discriminator_type
883     *                  the type of the union discriminator.
884     * @param members   an array describing the members of the TypeCode.
885     * @return          the requested TypeCode.
886     */
887    public synchronized TypeCode create_union_tc(String id,
888                                    String name,
889                                    TypeCode discriminator_type,
890                                    UnionMember[] members)
891    {
892        checkShutdownState();
893        return new TypeCodeImpl(this,
894                                TCKind._tk_union,
895                                id,
896                                name,
897                                discriminator_type,
898                                members);
899    }
900
901    /**
902     * Create a TypeCode for an enum.
903     *
904     * @param id                the logical id for the typecode.
905     * @param name      the name for the typecode.
906     * @param members   an array describing the members of the TypeCode.
907     * @return          the requested TypeCode.
908     */
909    public synchronized TypeCode create_enum_tc(String id,
910                                   String name,
911                                   String[] members)
912    {
913        checkShutdownState();
914        return new TypeCodeImpl(this, TCKind._tk_enum, id, name, members);
915    }
916
917    /**
918     * Create a TypeCode for an alias.
919     *
920     * @param id                the logical id for the typecode.
921     * @param name      the name for the typecode.
922     * @param original_type
923     *                  the type this is an alias for.
924     * @return          the requested TypeCode.
925     */
926    public synchronized TypeCode create_alias_tc(String id,
927                                    String name,
928                                    TypeCode original_type)
929    {
930        checkShutdownState();
931        return new TypeCodeImpl(this, TCKind._tk_alias, id, name, original_type);
932    }
933
934    /**
935     * Create a TypeCode for an exception.
936     *
937     * @param id                the logical id for the typecode.
938     * @param name      the name for the typecode.
939     * @param members   an array describing the members of the TypeCode.
940     * @return          the requested TypeCode.
941     */
942    public synchronized TypeCode create_exception_tc(String id,
943                                        String name,
944                                        StructMember[] members)
945    {
946        checkShutdownState();
947        return new TypeCodeImpl(this, TCKind._tk_except, id, name, members);
948    }
949
950    /**
951     * Create a TypeCode for an interface.
952     *
953     * @param id                the logical id for the typecode.
954     * @param name      the name for the typecode.
955     * @return          the requested TypeCode.
956     */
957    public synchronized TypeCode create_interface_tc(String id,
958                                        String name)
959    {
960        checkShutdownState();
961        return new TypeCodeImpl(this, TCKind._tk_objref, id, name);
962    }
963
964    /**
965     * Create a TypeCode for a string.
966     *
967     * @param bound     the bound for the string.
968     * @return          the requested TypeCode.
969     */
970    public synchronized TypeCode create_string_tc(int bound)
971    {
972        checkShutdownState();
973        return new TypeCodeImpl(this, TCKind._tk_string, bound);
974    }
975
976    /**
977     * Create a TypeCode for a wide string.
978     *
979     * @param bound     the bound for the string.
980     * @return          the requested TypeCode.
981     */
982    public synchronized TypeCode create_wstring_tc(int bound)
983    {
984        checkShutdownState();
985        return new TypeCodeImpl(this, TCKind._tk_wstring, bound);
986    }
987
988    /**
989     * Create a TypeCode for a sequence.
990     *
991     * @param bound     the bound for the sequence.
992     * @param element_type
993     *                  the type of elements of the sequence.
994     * @return          the requested TypeCode.
995     */
996    public synchronized TypeCode create_sequence_tc(int bound,
997                                       TypeCode element_type)
998    {
999        checkShutdownState();
1000        return new TypeCodeImpl(this, TCKind._tk_sequence, bound, element_type);
1001    }
1002
1003
1004    /**
1005     * Create a recursive TypeCode in a sequence.
1006     *
1007     * @param bound     the bound for the sequence.
1008     * @param offset    the index to the enclosing TypeCode that is
1009     *                  being referenced.
1010     * @return          the requested TypeCode.
1011     */
1012    public synchronized TypeCode create_recursive_sequence_tc(int bound,
1013                                                 int offset)
1014    {
1015        checkShutdownState();
1016        return new TypeCodeImpl(this, TCKind._tk_sequence, bound, offset);
1017    }
1018
1019
1020    /**
1021     * Create a TypeCode for an array.
1022     *
1023     * @param length    the length of the array.
1024     * @param element_type
1025     *                  the type of elements of the array.
1026     * @return          the requested TypeCode.
1027     */
1028    public synchronized TypeCode create_array_tc(int length,
1029                                    TypeCode element_type)
1030    {
1031        checkShutdownState();
1032        return new TypeCodeImpl(this, TCKind._tk_array, length, element_type);
1033    }
1034
1035
1036    public synchronized org.omg.CORBA.TypeCode create_native_tc(String id,
1037                                                   String name)
1038    {
1039        checkShutdownState();
1040        return new TypeCodeImpl(this, TCKind._tk_native, id, name);
1041    }
1042
1043    public synchronized org.omg.CORBA.TypeCode create_abstract_interface_tc(
1044                                                               String id,
1045                                                               String name)
1046    {
1047        checkShutdownState();
1048        return new TypeCodeImpl(this, TCKind._tk_abstract_interface, id, name);
1049    }
1050
1051    public synchronized org.omg.CORBA.TypeCode create_fixed_tc(short digits, short scale)
1052    {
1053        checkShutdownState();
1054        return new TypeCodeImpl(this, TCKind._tk_fixed, digits, scale);
1055    }
1056
1057    public synchronized org.omg.CORBA.TypeCode create_value_tc(String id,
1058                                                  String name,
1059                                                  short type_modifier,
1060                                                  TypeCode concrete_base,
1061                                                  ValueMember[] members)
1062    {
1063        checkShutdownState();
1064        return new TypeCodeImpl(this, TCKind._tk_value, id, name,
1065                                type_modifier, concrete_base, members);
1066    }
1067
1068    public synchronized org.omg.CORBA.TypeCode create_recursive_tc(String id) {
1069        checkShutdownState();
1070        return new TypeCodeImpl(this, id);
1071    }
1072
1073    public synchronized org.omg.CORBA.TypeCode create_value_box_tc(String id,
1074                                                      String name,
1075                                                      TypeCode boxed_type)
1076    {
1077        checkShutdownState();
1078        return new TypeCodeImpl(this, TCKind._tk_value_box, id, name,
1079            boxed_type);
1080    }
1081
1082    /**
1083     * Create a new Any
1084     *
1085     * @return          the new Any created.
1086     */
1087    public synchronized Any create_any()
1088    {
1089        checkShutdownState();
1090        return new AnyImpl(this);
1091    }
1092
1093    // TypeCodeFactory interface methods.
1094    // Keeping track of type codes by repository id.
1095
1096    // Keeping a cache of TypeCodes associated with the class
1097    // they got created from in Util.writeAny().
1098
1099    public synchronized void setTypeCodeForClass(Class c, TypeCodeImpl tci)
1100    {
1101        checkShutdownState();
1102
1103        if (typeCodeForClassMap == null)
1104            typeCodeForClassMap = Collections.synchronizedMap(
1105                new WeakHashMap(64));
1106        // Store only one TypeCode per class.
1107        if ( ! typeCodeForClassMap.containsKey(c))
1108            typeCodeForClassMap.put(c, tci);
1109    }
1110
1111    public synchronized TypeCodeImpl getTypeCodeForClass(Class c)
1112    {
1113        checkShutdownState();
1114
1115        if (typeCodeForClassMap == null)
1116            return null;
1117        return (TypeCodeImpl)typeCodeForClassMap.get(c);
1118    }
1119
1120/****************************************************************************
1121 * The following methods deal with listing and resolving the initial
1122 * (bootstrap) object references such as "NameService".
1123 ****************************************************************************/
1124
1125    /**
1126     * Get a list of the initially available CORBA services.
1127     * This does not work unless an ORBInitialHost is specified during
1128     * initialization (or unless there is an ORB running on the AppletHost)
1129     * since the localhostname
1130     * is inaccessible to applets. If a service properties URL was specified,
1131     * then it is used, otherwise the bootstrapping protocol is used.
1132     * @return A list of the initial services available.
1133     */
1134    public String[] list_initial_services()
1135    {
1136        Resolver res ;
1137
1138        synchronized( this ) {
1139            checkShutdownState();
1140            res = resolver ;
1141        }
1142
1143        synchronized (resolverLock) {
1144            java.util.Set keys = res.list() ;
1145            return (String[])keys.toArray( new String[keys.size()] ) ;
1146        }
1147    }
1148
1149    /**
1150     * Resolve the stringified reference of one of the initially
1151     * available CORBA services.
1152     * @param identifier The stringified object reference of the
1153     * desired service.
1154     * @return An object reference for the desired service.
1155     * @exception InvalidName The supplied identifier is not associated
1156     * with a known service.
1157     * @exception SystemException One of a fixed set of Corba system exceptions.
1158     */
1159    public org.omg.CORBA.Object resolve_initial_references(
1160        String identifier) throws InvalidName
1161    {
1162        Resolver res ;
1163
1164        synchronized( this ) {
1165            checkShutdownState();
1166            res = resolver ;
1167        }
1168
1169        synchronized (resolverLock) {
1170            org.omg.CORBA.Object result = res.resolve( identifier ) ;
1171
1172            if (result == null)
1173                throw new InvalidName() ;
1174            else
1175                return result ;
1176        }
1177    }
1178
1179    /**
1180     * If this operation is called with an id, <code>"Y"</code>, and an
1181     * object, <code>YY</code>, then a subsequent call to
1182     * <code>ORB.resolve_initial_references( "Y" )</code> will
1183     * return object <code>YY</code>.
1184     *
1185     * @param id The ID by which the initial reference will be known.
1186     * @param obj The initial reference itself.
1187     * @throws InvalidName if this operation is called with an empty string id
1188     *     or this operation is called with an id that is already registered,
1189     *     including the default names defined by OMG.
1190     * @throws BAD_PARAM if the obj parameter is null.
1191     */
1192    public void register_initial_reference(
1193        String id, org.omg.CORBA.Object obj ) throws InvalidName
1194    {
1195        CorbaServerRequestDispatcher insnd ;
1196
1197        synchronized (this) {
1198            checkShutdownState();
1199        }
1200
1201        if ((id == null) || (id.length() == 0))
1202            throw new InvalidName() ;
1203
1204        synchronized (this) {
1205            checkShutdownState();
1206        }
1207
1208        synchronized (resolverLock) {
1209            insnd = insNamingDelegate ;
1210
1211            java.lang.Object obj2 = localResolver.resolve( id ) ;
1212            if (obj2 != null)
1213                throw new InvalidName(id + " already registered") ;
1214
1215            localResolver.register( id, ClosureFactory.makeConstant( obj )) ;
1216        }
1217
1218        synchronized (this) {
1219            if (StubAdapter.isStub(obj))
1220                // Make all remote object references available for INS.
1221                requestDispatcherRegistry.registerServerRequestDispatcher(
1222                    insnd, id ) ;
1223        }
1224    }
1225
1226/****************************************************************************
1227 * The following methods (introduced in POA / CORBA2.1) deal with
1228 * shutdown / single threading.
1229 ****************************************************************************/
1230
1231    public void run()
1232    {
1233        synchronized (this) {
1234            checkShutdownState();
1235        }
1236
1237        synchronized (runObj) {
1238            try {
1239                runObj.wait();
1240            } catch ( InterruptedException ex ) {}
1241        }
1242    }
1243
1244    public void shutdown(boolean wait_for_completion) {
1245        boolean wait = false;
1246
1247        synchronized (this) {
1248            checkShutdownState();
1249
1250            // This is to avoid deadlock: don't allow a thread that is
1251            // processing a request to call shutdown( true ), because
1252            // the shutdown would block waiting for the request to complete,
1253            // while the request would block waiting for shutdown to complete.
1254            if (wait_for_completion &&
1255                isProcessingInvocation.get() == Boolean.TRUE) {
1256                throw omgWrapper.shutdownWaitForCompletionDeadlock();
1257            }
1258
1259            if (status == STATUS_SHUTTING_DOWN) {
1260                if (wait_for_completion) {
1261                    wait = true;
1262                } else {
1263                    return;
1264                }
1265            }
1266
1267            status = STATUS_SHUTTING_DOWN;
1268        }
1269
1270        // Avoid more than one thread performing shutdown at a time.
1271        synchronized (shutdownObj) {
1272            // At this point, the ORB status is certainly STATUS_SHUTTING_DOWN.
1273            // If wait is true, another thread already called shutdown( true ),
1274            // and so we wait for completion
1275            if (wait) {
1276                while (true) {
1277                    synchronized (this) {
1278                        if (status == STATUS_SHUTDOWN)
1279                            break;
1280                    }
1281
1282                    try {
1283                        shutdownObj.wait();
1284                    } catch (InterruptedException exc) {
1285                        // NOP: just loop and wait until state is changed
1286                    }
1287                }
1288            } else {
1289                // perform the actual shutdown
1290                shutdownServants(wait_for_completion);
1291
1292                if (wait_for_completion) {
1293                    synchronized ( waitForCompletionObj ) {
1294                        while (numInvocations > 0) {
1295                            try {
1296                                waitForCompletionObj.wait();
1297                            } catch (InterruptedException ex) {}
1298                        }
1299                    }
1300                }
1301
1302                synchronized (runObj) {
1303                    runObj.notifyAll();
1304                }
1305
1306                status = STATUS_SHUTDOWN;
1307
1308                shutdownObj.notifyAll();
1309            }
1310        }
1311    }
1312
1313    // Cause all ObjectAdapaterFactories to clean up all of their internal state, which
1314    // may include activated objects that have associated state and callbacks that must
1315    // complete in order to shutdown.  This will cause new request to be rejected.
1316    protected void shutdownServants(boolean wait_for_completion) {
1317        Set<ObjectAdapterFactory> oaset;
1318        synchronized (this) {
1319            oaset = new HashSet<>(requestDispatcherRegistry.getObjectAdapterFactories());
1320        }
1321
1322        for (ObjectAdapterFactory oaf : oaset)
1323            oaf.shutdown(wait_for_completion);
1324    }
1325
1326    // Note that the caller must hold the ORBImpl lock.
1327    public void checkShutdownState()
1328    {
1329        if (status == STATUS_DESTROYED) {
1330            throw wrapper.orbDestroyed() ;
1331        }
1332
1333        if (status == STATUS_SHUTDOWN) {
1334            throw omgWrapper.badOperationAfterShutdown() ;
1335        }
1336    }
1337
1338    public boolean isDuringDispatch()
1339    {
1340        synchronized (this) {
1341                checkShutdownState();
1342        }
1343        Boolean value = (Boolean)(isProcessingInvocation.get()) ;
1344        return value.booleanValue() ;
1345    }
1346
1347    public void startingDispatch()
1348    {
1349        synchronized (this) {
1350                checkShutdownState();
1351        }
1352        synchronized (invocationObj) {
1353            isProcessingInvocation.set(Boolean.TRUE);
1354            numInvocations++;
1355        }
1356    }
1357
1358    public void finishedDispatch()
1359    {
1360        synchronized (this) {
1361                checkShutdownState();
1362        }
1363        synchronized (invocationObj) {
1364            numInvocations--;
1365            isProcessingInvocation.set(false);
1366            if (numInvocations == 0) {
1367                synchronized (waitForCompletionObj) {
1368                    waitForCompletionObj.notifyAll();
1369                }
1370            } else if (numInvocations < 0) {
1371                throw wrapper.numInvocationsAlreadyZero(
1372                    CompletionStatus.COMPLETED_YES);
1373            }
1374        }
1375    }
1376
1377    /**
1378     *  formal/99-10-07 p 159: "If destroy is called on an ORB that has
1379     *  not been shut down, it will start the shutdown process and block until
1380     *  the ORB has shut down before it destroys the ORB."
1381     */
1382    public void destroy()
1383    {
1384        boolean shutdownFirst = false;
1385
1386        synchronized (this) {
1387            shutdownFirst = (status == STATUS_OPERATING);
1388        }
1389
1390        if (shutdownFirst) {
1391            shutdown(true);
1392        }
1393
1394        synchronized (this) {
1395            if (status < STATUS_DESTROYED) {
1396                getCorbaTransportManager().close();
1397                getPIHandler().destroyInterceptors();
1398                status = STATUS_DESTROYED;
1399            }
1400        }
1401        synchronized (threadPoolManagerAccessLock) {
1402            if (orbOwnsThreadPoolManager) {
1403                try {
1404                    threadpoolMgr.close();
1405                    threadpoolMgr = null;
1406                } catch (IOException exc) {
1407                    wrapper.ioExceptionOnClose(exc);
1408                }
1409            }
1410        }
1411
1412        try {
1413            monitoringManager.close();
1414            monitoringManager = null;
1415        } catch (IOException exc) {
1416            wrapper.ioExceptionOnClose(exc);
1417        }
1418
1419        CachedCodeBase.cleanCache(this);
1420        try {
1421            pihandler.close();
1422        } catch (IOException exc) {
1423            wrapper.ioExceptionOnClose(exc);
1424        }
1425
1426        super.destroy();
1427
1428        badServerIdHandlerAccessLock = null;
1429        clientDelegateFactoryAccessorLock = null;
1430        corbaContactInfoListFactoryAccessLock = null;
1431
1432        objectKeyFactoryAccessLock = null;
1433        legacyServerSocketManagerAccessLock = null;
1434        threadPoolManagerAccessLock = null;
1435        transportManager = null;
1436        legacyServerSocketManager = null;
1437        OAInvocationInfoStack  = null;
1438        clientInvocationInfoStack  = null;
1439        codeBaseIOR = null;
1440        dynamicRequests  = null;
1441        svResponseReceived  = null;
1442        runObj = null;
1443        shutdownObj = null;
1444        waitForCompletionObj = null;
1445        invocationObj = null;
1446        isProcessingInvocation = null;
1447        typeCodeForClassMap  = null;
1448        valueFactoryCache = null;
1449        orbVersionThreadLocal = null;
1450        requestDispatcherRegistry = null;
1451        copierManager = null;
1452        toaFactory = null;
1453        poaFactory = null;
1454        pihandler = null;
1455        configData = null;
1456        badServerIdHandler = null;
1457        clientDelegateFactory = null;
1458        corbaContactInfoListFactory = null;
1459        resolver = null;
1460        localResolver = null;
1461        insNamingDelegate = null;
1462        urlOperation = null;
1463        taggedComponentFactoryFinder = null;
1464        taggedProfileFactoryFinder = null;
1465        taggedProfileTemplateFactoryFinder = null;
1466        objectKeyFactory = null;
1467    }
1468
1469    /**
1470     * Registers a value factory for a particular repository ID.
1471     *
1472     * @param repositoryID the repository ID.
1473     * @param factory the factory.
1474     * @return the previously registered factory for the given repository ID,
1475     * or null if no such factory was previously registered.
1476     * @exception org.omg.CORBA.BAD_PARAM if the registration fails.
1477     **/
1478    public synchronized ValueFactory register_value_factory(String repositoryID,
1479        ValueFactory factory)
1480    {
1481        checkShutdownState();
1482
1483        if ((repositoryID == null) || (factory == null))
1484            throw omgWrapper.unableRegisterValueFactory() ;
1485
1486        return (ValueFactory)valueFactoryCache.put(repositoryID, factory);
1487    }
1488
1489    /**
1490     * Unregisters a value factory for a particular repository ID.
1491     *
1492     * @param repositoryID the repository ID.
1493     **/
1494    public synchronized void unregister_value_factory(String repositoryID)
1495    {
1496        checkShutdownState();
1497
1498        if (valueFactoryCache.remove(repositoryID) == null)
1499            throw wrapper.nullParam() ;
1500    }
1501
1502    /**
1503     * Finds and returns a value factory for the given repository ID.
1504     * The value factory returned was previously registered by a call to
1505     * {@link #register_value_factory} or is the default factory.
1506     *
1507     * @param repositoryID the repository ID.
1508     * @return the value factory.
1509     * @exception org.omg.CORBA.BAD_PARAM if unable to locate a factory.
1510     **/
1511    public synchronized ValueFactory lookup_value_factory(String repositoryID)
1512    {
1513        checkShutdownState();
1514
1515        ValueFactory factory =
1516            (ValueFactory)valueFactoryCache.get(repositoryID);
1517
1518        if (factory == null) {
1519            try {
1520                factory = Utility.getFactory(null, null, null, repositoryID);
1521            } catch(org.omg.CORBA.MARSHAL ex) {
1522                throw wrapper.unableFindValueFactory( ex ) ;
1523            }
1524        }
1525
1526        return factory ;
1527    }
1528
1529    public OAInvocationInfo peekInvocationInfo()
1530    {
1531        synchronized (this) {
1532                checkShutdownState();
1533        }
1534        StackImpl stack = (StackImpl)(OAInvocationInfoStack.get()) ;
1535        return (OAInvocationInfo)(stack.peek()) ;
1536    }
1537
1538    public void pushInvocationInfo( OAInvocationInfo info )
1539    {
1540        synchronized (this) {
1541                checkShutdownState();
1542        }
1543        StackImpl stack = (StackImpl)(OAInvocationInfoStack.get()) ;
1544        stack.push( info ) ;
1545    }
1546
1547    public OAInvocationInfo popInvocationInfo()
1548    {
1549        synchronized (this) {
1550                checkShutdownState();
1551        }
1552        StackImpl stack = (StackImpl)(OAInvocationInfoStack.get()) ;
1553        return (OAInvocationInfo)(stack.pop()) ;
1554    }
1555
1556    /**
1557     * The bad server id handler is used by the Locator to
1558     * send back the location of a persistant server to the client.
1559     */
1560
1561    private Object badServerIdHandlerAccessLock = new Object();
1562
1563    public void initBadServerIdHandler()
1564    {
1565        synchronized (this) {
1566                checkShutdownState();
1567        }
1568        synchronized (badServerIdHandlerAccessLock) {
1569            Class cls = configData.getBadServerIdHandler() ;
1570            if (cls != null) {
1571                try {
1572                    Class[] params = new Class[] { org.omg.CORBA.ORB.class };
1573                    java.lang.Object[] args = new java.lang.Object[]{this};
1574                    Constructor cons = cls.getConstructor(params);
1575                    badServerIdHandler =
1576                        (BadServerIdHandler) cons.newInstance(args);
1577                } catch (Exception e) {
1578                    throw wrapper.errorInitBadserveridhandler( e ) ;
1579                }
1580            }
1581        }
1582    }
1583
1584    public void setBadServerIdHandler( BadServerIdHandler handler )
1585    {
1586        synchronized (this) {
1587                checkShutdownState();
1588        }
1589        synchronized (badServerIdHandlerAccessLock) {
1590            badServerIdHandler = handler;
1591        }
1592    }
1593
1594    public void handleBadServerId( ObjectKey okey )
1595    {
1596        synchronized (this) {
1597                checkShutdownState();
1598        }
1599        synchronized (badServerIdHandlerAccessLock) {
1600            if (badServerIdHandler == null)
1601                throw wrapper.badServerId() ;
1602            else
1603                badServerIdHandler.handle( okey ) ;
1604        }
1605    }
1606
1607    public synchronized org.omg.CORBA.Policy create_policy( int type,
1608        org.omg.CORBA.Any val ) throws org.omg.CORBA.PolicyError
1609    {
1610        checkShutdownState() ;
1611
1612        return pihandler.create_policy( type, val ) ;
1613    }
1614
1615    /** This is the implementation of the public API used to connect
1616     *  a servant-skeleton to the ORB.
1617     */
1618    public synchronized void connect(org.omg.CORBA.Object servant)
1619    {
1620        checkShutdownState();
1621        if (getTOAFactory() == null)
1622            throw wrapper.noToa() ;
1623
1624        try {
1625            String codebase = javax.rmi.CORBA.Util.getCodebase( servant.getClass() ) ;
1626            getTOAFactory().getTOA( codebase ).connect( servant ) ;
1627        } catch ( Exception ex ) {
1628            throw wrapper.orbConnectError( ex ) ;
1629        }
1630    }
1631
1632    public synchronized void disconnect(org.omg.CORBA.Object obj)
1633    {
1634        checkShutdownState();
1635        if (getTOAFactory() == null)
1636            throw wrapper.noToa() ;
1637
1638        try {
1639            getTOAFactory().getTOA().disconnect( obj ) ;
1640        } catch ( Exception ex ) {
1641            throw wrapper.orbConnectError( ex ) ;
1642        }
1643    }
1644
1645    public int getTransientServerId()
1646    {
1647        synchronized (this) {
1648                checkShutdownState();
1649        }
1650        if( configData.getORBServerIdPropertySpecified( ) ) {
1651            // ORBServerId is specified then use that value
1652            return configData.getPersistentServerId( );
1653        }
1654        return transientServerId;
1655    }
1656
1657    public RequestDispatcherRegistry getRequestDispatcherRegistry()
1658    {
1659        synchronized (this) {
1660                checkShutdownState();
1661        }
1662        return requestDispatcherRegistry;
1663    }
1664
1665    public ServiceContextRegistry getServiceContextRegistry()
1666    {
1667        synchronized (this) {
1668                checkShutdownState();
1669        }
1670        return serviceContextRegistry ;
1671    }
1672
1673    // XXX All of the isLocalXXX checking needs to be revisited.
1674    // First of all, all three of these methods are called from
1675    // only one place in impl.ior.IORImpl.  Second, we have problems
1676    // both with multi-homed hosts and with multi-profile IORs.
1677    // A possible strategy: like the LocalClientRequestDispatcher, we need
1678    // to determine this more abstractly at the ContactInfo level.
1679    // This level should probably just get the CorbaContactInfoList from
1680    // the IOR, then iterator over ContactInfo.  If any ContactInfo is
1681    // local, the IOR is local, and we can pick one to create the
1682    // LocalClientRequestDispatcher as well.  Bottom line: this code needs to move.
1683
1684    // XXX What about multi-homed host?
1685    public boolean isLocalHost( String hostName )
1686    {
1687        synchronized (this) {
1688                checkShutdownState();
1689        }
1690        return hostName.equals( configData.getORBServerHost() ) ||
1691            hostName.equals( getLocalHostName() ) ;
1692    }
1693
1694    public boolean isLocalServerId( int subcontractId, int serverId )
1695    {
1696        synchronized (this) {
1697                checkShutdownState();
1698        }
1699        if ((subcontractId < ORBConstants.FIRST_POA_SCID) ||
1700            (subcontractId > ORBConstants.MAX_POA_SCID))
1701            return serverId == getTransientServerId( ) ;
1702
1703        // XXX isTransient info should be stored in subcontract registry
1704        if (ORBConstants.isTransient( subcontractId ))
1705            return (serverId == getTransientServerId()) ;
1706        else if (configData.getPersistentServerIdInitialized())
1707            return (serverId == configData.getPersistentServerId()) ;
1708        else
1709            return false ;
1710    }
1711
1712    /*************************************************************************
1713     *  The following public methods are for ORB shutdown.
1714     *************************************************************************/
1715
1716    private String getHostName(String host)
1717        throws java.net.UnknownHostException
1718    {
1719        return InetAddress.getByName( host ).getHostAddress();
1720    }
1721
1722    /* keeping a copy of the getLocalHostName so that it can only be called
1723     * internally and the unauthorized clients cannot have access to the
1724     * localHost information, originally, the above code was calling
1725     * getLocalHostName from Connection.java.  If the hostname is cached in
1726     * Connection.java, then
1727     * it is a security hole, since any unauthorized client has access to
1728     * the host information.  With this change it is used internally so the
1729     * security problem is resolved.  Also in Connection.java, the
1730     * getLocalHost() implementation has changed to always call the
1731     * InetAddress.getLocalHost().getHostAddress()
1732     * The above mentioned method has been removed from the connection class
1733     */
1734
1735    private static String localHostString = null;
1736
1737    private synchronized String getLocalHostName()
1738    {
1739        if (localHostString == null) {
1740            try {
1741                localHostString = InetAddress.getLocalHost().getHostAddress();
1742            } catch (Exception ex) {
1743                throw wrapper.getLocalHostFailed( ex ) ;
1744            }
1745        }
1746        return localHostString ;
1747    }
1748
1749 /******************************************************************************
1750 *  The following public methods are for ORB shutdown.
1751 *
1752 ******************************************************************************/
1753
1754    /** This method always returns false because the ORB never needs the
1755     *  main thread to do work.
1756     */
1757    public synchronized boolean work_pending()
1758    {
1759        checkShutdownState();
1760        throw wrapper.genericNoImpl() ;
1761    }
1762
1763    /** This method does nothing. It is not required by the spec to do anything!
1764     */
1765    public synchronized void perform_work()
1766    {
1767        checkShutdownState();
1768        throw wrapper.genericNoImpl() ;
1769    }
1770
1771    public synchronized void set_delegate(java.lang.Object servant){
1772        checkShutdownState();
1773
1774        POAFactory poaFactory = getPOAFactory() ;
1775        if (poaFactory != null)
1776            ((org.omg.PortableServer.Servant)servant)
1777                ._set_delegate( poaFactory.getDelegateImpl() ) ;
1778        else
1779            throw wrapper.noPoa() ;
1780    }
1781
1782    ////////////////////////////////////////////////////
1783    //
1784    // pept.broker.Broker
1785    //
1786
1787    public ClientInvocationInfo createOrIncrementInvocationInfo()
1788    {
1789        synchronized (this) {
1790                checkShutdownState();
1791        }
1792        StackImpl invocationInfoStack =
1793            (StackImpl) clientInvocationInfoStack.get();
1794        ClientInvocationInfo clientInvocationInfo = null;
1795        if (!invocationInfoStack.empty()) {
1796            clientInvocationInfo =
1797                (ClientInvocationInfo) invocationInfoStack.peek();
1798        }
1799        if ((clientInvocationInfo == null) ||
1800            (!clientInvocationInfo.isRetryInvocation()))
1801        {
1802            // This is a new call - not a retry.
1803            clientInvocationInfo = new CorbaInvocationInfo(this);
1804            startingDispatch();
1805            invocationInfoStack.push(clientInvocationInfo);
1806        }
1807        // Reset retry so recursive calls will get a new info object.
1808        clientInvocationInfo.setIsRetryInvocation(false);
1809        clientInvocationInfo.incrementEntryCount();
1810        return clientInvocationInfo;
1811    }
1812
1813    public void releaseOrDecrementInvocationInfo()
1814    {
1815        synchronized (this) {
1816                checkShutdownState();
1817        }
1818        int entryCount = -1;
1819        ClientInvocationInfo clientInvocationInfo = null;
1820        StackImpl invocationInfoStack =
1821            (StackImpl)clientInvocationInfoStack.get();
1822        if (!invocationInfoStack.empty()) {
1823            clientInvocationInfo =
1824                (ClientInvocationInfo)invocationInfoStack.peek();
1825        } else {
1826            throw wrapper.invocationInfoStackEmpty() ;
1827        }
1828        clientInvocationInfo.decrementEntryCount();
1829        entryCount = clientInvocationInfo.getEntryCount();
1830        if (clientInvocationInfo.getEntryCount() == 0) {
1831            // 6763340: don't pop if this is a retry!
1832            if (!clientInvocationInfo.isRetryInvocation()) {
1833                invocationInfoStack.pop();
1834            }
1835            finishedDispatch();
1836        }
1837    }
1838
1839    public ClientInvocationInfo getInvocationInfo()
1840    {
1841        synchronized (this) {
1842                checkShutdownState();
1843        }
1844        StackImpl invocationInfoStack =
1845            (StackImpl) clientInvocationInfoStack.get();
1846        return (ClientInvocationInfo) invocationInfoStack.peek();
1847    }
1848
1849    ////////////////////////////////////////////////////
1850    //
1851    //
1852    //
1853
1854    private Object clientDelegateFactoryAccessorLock = new Object();
1855
1856    public void setClientDelegateFactory( ClientDelegateFactory factory )
1857    {
1858        synchronized (this) {
1859                checkShutdownState();
1860        }
1861        synchronized (clientDelegateFactoryAccessorLock) {
1862            clientDelegateFactory = factory ;
1863        }
1864    }
1865
1866    public ClientDelegateFactory getClientDelegateFactory()
1867    {
1868        synchronized (this) {
1869                checkShutdownState();
1870        }
1871        synchronized (clientDelegateFactoryAccessorLock) {
1872            return clientDelegateFactory ;
1873        }
1874    }
1875
1876    private Object corbaContactInfoListFactoryAccessLock = new Object();
1877
1878    public void setCorbaContactInfoListFactory( CorbaContactInfoListFactory factory )
1879    {
1880        synchronized (this) {
1881                checkShutdownState();
1882        }
1883        synchronized (corbaContactInfoListFactoryAccessLock) {
1884            corbaContactInfoListFactory = factory ;
1885        }
1886    }
1887
1888    public synchronized CorbaContactInfoListFactory getCorbaContactInfoListFactory()
1889    {
1890        checkShutdownState();
1891        return corbaContactInfoListFactory ;
1892    }
1893
1894    /** Set the resolver used in this ORB.  This resolver will be used for list_initial_services
1895     * and resolve_initial_references.
1896     */
1897    public void setResolver( Resolver resolver )
1898    {
1899        synchronized (this) {
1900                checkShutdownState();
1901        }
1902        synchronized (resolverLock) {
1903            this.resolver = resolver ;
1904        }
1905    }
1906
1907    /** Get the resolver used in this ORB.  This resolver will be used for list_initial_services
1908     * and resolve_initial_references.
1909     */
1910    public Resolver getResolver()
1911    {
1912        synchronized (this) {
1913                checkShutdownState();
1914        }
1915        synchronized (resolverLock) {
1916            return resolver ;
1917        }
1918    }
1919
1920    /** Set the LocalResolver used in this ORB.  This LocalResolver is used for
1921     * register_initial_reference only.
1922     */
1923    public void setLocalResolver( LocalResolver resolver )
1924    {
1925        synchronized (this) {
1926                checkShutdownState();
1927        }
1928        synchronized (resolverLock) {
1929            this.localResolver = resolver ;
1930        }
1931    }
1932
1933    /** Get the LocalResolver used in this ORB.  This LocalResolver is used for
1934     * register_initial_reference only.
1935     */
1936    public LocalResolver getLocalResolver()
1937    {
1938        synchronized (this) {
1939                checkShutdownState();
1940        }
1941        synchronized (resolverLock) {
1942            return localResolver ;
1943        }
1944    }
1945
1946    /** Set the operation used in string_to_object calls.  The Operation must expect a
1947     * String and return an org.omg.CORBA.Object.
1948     */
1949    public void setURLOperation( Operation stringToObject )
1950    {
1951        synchronized (this) {
1952                checkShutdownState();
1953        }
1954        synchronized (urlOperationLock) {
1955            urlOperation = stringToObject ;
1956        }
1957    }
1958
1959    /** Get the operation used in string_to_object calls.  The Operation must expect a
1960     * String and return an org.omg.CORBA.Object.
1961     */
1962    public Operation getURLOperation()
1963    {
1964        synchronized (this) {
1965                checkShutdownState();
1966        }
1967        synchronized (urlOperationLock) {
1968            return urlOperation ;
1969        }
1970    }
1971
1972    public void setINSDelegate( CorbaServerRequestDispatcher sdel )
1973    {
1974        synchronized (this) {
1975                checkShutdownState();
1976        }
1977        synchronized (resolverLock) {
1978            insNamingDelegate = sdel ;
1979        }
1980    }
1981
1982    public TaggedComponentFactoryFinder getTaggedComponentFactoryFinder()
1983    {
1984        synchronized (this) {
1985                checkShutdownState();
1986        }
1987        return taggedComponentFactoryFinder ;
1988    }
1989
1990    public IdentifiableFactoryFinder getTaggedProfileFactoryFinder()
1991    {
1992        synchronized (this) {
1993                checkShutdownState();
1994        }
1995        return taggedProfileFactoryFinder ;
1996    }
1997
1998    public IdentifiableFactoryFinder getTaggedProfileTemplateFactoryFinder()
1999    {
2000        synchronized (this) {
2001                checkShutdownState();
2002        }
2003        return taggedProfileTemplateFactoryFinder ;
2004    }
2005
2006    private Object objectKeyFactoryAccessLock = new Object();
2007
2008    public ObjectKeyFactory getObjectKeyFactory()
2009    {
2010        synchronized (this) {
2011                checkShutdownState();
2012        }
2013        synchronized (objectKeyFactoryAccessLock) {
2014            return objectKeyFactory ;
2015        }
2016    }
2017
2018    public void setObjectKeyFactory( ObjectKeyFactory factory )
2019    {
2020        synchronized (this) {
2021                checkShutdownState();
2022        }
2023        synchronized (objectKeyFactoryAccessLock) {
2024            objectKeyFactory = factory ;
2025        }
2026    }
2027
2028    private Object transportManagerAccessorLock = new Object();
2029
2030    public TransportManager getTransportManager()
2031    {
2032        synchronized (transportManagerAccessorLock) {
2033            if (transportManager == null) {
2034                transportManager = new CorbaTransportManagerImpl(this);
2035            }
2036            return transportManager;
2037        }
2038    }
2039
2040    public CorbaTransportManager getCorbaTransportManager()
2041    {
2042        return (CorbaTransportManager) getTransportManager();
2043    }
2044
2045    private Object legacyServerSocketManagerAccessLock = new Object();
2046
2047    public LegacyServerSocketManager getLegacyServerSocketManager()
2048    {
2049        synchronized (this) {
2050                checkShutdownState();
2051        }
2052        synchronized (legacyServerSocketManagerAccessLock) {
2053            if (legacyServerSocketManager == null) {
2054                legacyServerSocketManager = new LegacyServerSocketManagerImpl(this);
2055            }
2056            return legacyServerSocketManager;
2057        }
2058    }
2059
2060    private Object threadPoolManagerAccessLock = new Object();
2061
2062    public void setThreadPoolManager(ThreadPoolManager mgr)
2063    {
2064        synchronized (this) {
2065                checkShutdownState();
2066        }
2067        synchronized (threadPoolManagerAccessLock) {
2068            threadpoolMgr = mgr;
2069        }
2070    }
2071
2072    public ThreadPoolManager getThreadPoolManager()
2073    {
2074        synchronized (this) {
2075                checkShutdownState();
2076        }
2077        synchronized (threadPoolManagerAccessLock) {
2078            if (threadpoolMgr == null) {
2079                threadpoolMgr = new ThreadPoolManagerImpl();
2080                orbOwnsThreadPoolManager = true;
2081            }
2082            return threadpoolMgr;
2083        }
2084    }
2085
2086    public CopierManager getCopierManager()
2087    {
2088        synchronized (this) {
2089                checkShutdownState();
2090        }
2091        return copierManager ;
2092    }
2093} // Class ORBImpl
2094
2095////////////////////////////////////////////////////////////////////////
2096/// Helper class for a Synchronization Variable
2097////////////////////////////////////////////////////////////////////////
2098
2099class SynchVariable
2100{
2101    // Synchronization Variable
2102    public boolean _flag;
2103
2104    // Constructor
2105    SynchVariable()
2106    {
2107        _flag = false;
2108    }
2109
2110    // set Flag to true
2111    public void set()
2112    {
2113        _flag = true;
2114    }
2115
2116        // get value
2117    public boolean value()
2118    {
2119        return _flag;
2120    }
2121
2122    // reset Flag to true
2123    public void reset()
2124    {
2125        _flag = false;
2126    }
2127}
2128
2129// End of file.
2130