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