ORB.java revision 709:1ee087da34d5
1/*
2 * Copyright (c) 2002, 2014, 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.spi.orb;
27
28import java.util.Map ;
29import java.util.HashMap ;
30import java.util.Properties ;
31import java.util.concurrent.ConcurrentHashMap;
32import java.util.logging.Logger ;
33
34import java.security.AccessController ;
35import java.security.PrivilegedAction ;
36
37import org.omg.CORBA.TCKind ;
38
39import com.sun.corba.se.pept.broker.Broker ;
40import com.sun.corba.se.pept.transport.ByteBufferPool;
41
42import com.sun.corba.se.spi.protocol.RequestDispatcherRegistry ;
43import com.sun.corba.se.spi.protocol.ClientDelegateFactory ;
44import com.sun.corba.se.spi.protocol.CorbaServerRequestDispatcher ;
45import com.sun.corba.se.spi.protocol.PIHandler ;
46import com.sun.corba.se.spi.resolver.LocalResolver ;
47import com.sun.corba.se.spi.resolver.Resolver ;
48import com.sun.corba.se.spi.transport.CorbaContactInfoListFactory ;
49import com.sun.corba.se.spi.legacy.connection.LegacyServerSocketManager;
50import com.sun.corba.se.spi.monitoring.MonitoringConstants;
51import com.sun.corba.se.spi.monitoring.MonitoringManager;
52import com.sun.corba.se.spi.monitoring.MonitoringFactories;
53
54import com.sun.corba.se.spi.ior.IdentifiableFactoryFinder ;
55import com.sun.corba.se.spi.ior.TaggedComponentFactoryFinder ;
56import com.sun.corba.se.spi.ior.ObjectKey ;
57import com.sun.corba.se.spi.ior.ObjectKeyFactory ;
58import com.sun.corba.se.spi.ior.IOR ;
59
60import com.sun.corba.se.spi.orbutil.threadpool.ThreadPoolManager;
61
62import com.sun.corba.se.spi.oa.OAInvocationInfo ;
63import com.sun.corba.se.spi.transport.CorbaTransportManager;
64
65import com.sun.corba.se.spi.logging.LogWrapperFactory ;
66import com.sun.corba.se.spi.logging.LogWrapperBase ;
67import com.sun.corba.se.spi.logging.CORBALogDomains ;
68
69import com.sun.corba.se.spi.copyobject.CopierManager ;
70
71import com.sun.corba.se.spi.presentation.rmi.PresentationManager ;
72import com.sun.corba.se.spi.presentation.rmi.PresentationDefaults ;
73
74import com.sun.corba.se.spi.servicecontext.ServiceContextRegistry ;
75
76// XXX needs an SPI or else it does not belong here
77import com.sun.corba.se.impl.corba.TypeCodeImpl ;
78import com.sun.corba.se.impl.corba.TypeCodeFactory ;
79
80// XXX Should there be a SPI level constants ?
81import com.sun.corba.se.impl.orbutil.ORBConstants ;
82
83import com.sun.corba.se.impl.oa.poa.BadServerIdHandler ;
84
85import com.sun.corba.se.impl.transport.ByteBufferPoolImpl;
86
87import com.sun.corba.se.impl.logging.ORBUtilSystemException ;
88import com.sun.corba.se.impl.logging.OMGSystemException ;
89
90import com.sun.corba.se.impl.presentation.rmi.PresentationManagerImpl ;
91
92import jdk.internal.misc.JavaAWTAccess;
93import jdk.internal.misc.SharedSecrets;
94
95public abstract class ORB extends com.sun.corba.se.org.omg.CORBA.ORB
96    implements Broker, TypeCodeFactory
97{
98    // As much as possible, this class should be stateless.  However,
99    // there are a few reasons why it is not:
100    //
101    // 1. The ORB debug flags are defined here because they are accessed
102    //    frequently, and we do not want a cast to the impl just for that.
103    // 2. typeCodeMap and primitiveTypeCodeConstants are here because they
104    //    are needed in both ORBImpl and ORBSingleton.
105    // 3. Logging support is here so that we can avoid problems with
106    //    incompletely initialized ORBs that need to perform logging.
107
108    // Flag set at compile time to debug flag processing: this can't
109    // be one of the xxxDebugFlags because it is used to debug the mechanism
110    // that sets the xxxDebugFlags!
111    public static boolean ORBInitDebug = false;
112
113    // Currently defined debug flags.  Any additions must be called xxxDebugFlag.
114    // All debug flags must be public boolean types.
115    // These are set by passing the flag -ORBDebug x,y,z in the ORB init args.
116    // Note that x,y,z must not contain spaces.
117    public boolean transportDebugFlag = false ;
118    public boolean subcontractDebugFlag = false ;
119    public boolean poaDebugFlag = false ;
120    public boolean poaConcurrencyDebugFlag = false ;
121    public boolean poaFSMDebugFlag = false ;
122    public boolean orbdDebugFlag = false ;
123    public boolean namingDebugFlag = false ;
124    public boolean serviceContextDebugFlag = false ;
125    public boolean transientObjectManagerDebugFlag = false ;
126    public boolean giopVersionDebugFlag = false;
127    public boolean shutdownDebugFlag = false;
128    public boolean giopDebugFlag = false;
129    public boolean invocationTimingDebugFlag = false ;
130
131    // SystemException log wrappers.  Protected so that they can be used in
132    // subclasses.
133    protected static ORBUtilSystemException staticWrapper ;
134    protected ORBUtilSystemException wrapper ;
135    protected OMGSystemException omgWrapper ;
136
137    // This map is needed for resolving recursive type code placeholders
138    // based on the unique repository id.
139    // XXX Should this be a WeakHashMap for GC?
140    private Map<String, TypeCodeImpl> typeCodeMap;
141
142    private TypeCodeImpl[] primitiveTypeCodeConstants;
143
144    // ByteBufferPool - needed by both ORBImpl and ORBSingleton
145    ByteBufferPool byteBufferPool;
146
147    // Local testing
148    // XXX clean this up, probably remove these
149    public abstract boolean isLocalHost( String hostName ) ;
150    public abstract boolean isLocalServerId( int subcontractId, int serverId ) ;
151
152    // Invocation stack manipulation
153    public abstract OAInvocationInfo peekInvocationInfo() ;
154    public abstract void pushInvocationInfo( OAInvocationInfo info ) ;
155    public abstract OAInvocationInfo popInvocationInfo() ;
156
157    public abstract CorbaTransportManager getCorbaTransportManager();
158    public abstract LegacyServerSocketManager getLegacyServerSocketManager();
159
160    // wrapperMap maintains a table of LogWrapper instances used by
161    // different classes to log exceptions.  The key is a StringPair
162    // representing LogDomain and ExceptionGroup.
163    private Map<StringPair, LogWrapperBase> wrapperMap;
164
165    static class Holder {
166        static final PresentationManager defaultPresentationManager =
167            setupPresentationManager();
168    }
169
170    private static final Map<Object, PresentationManager> pmContexts =
171            new ConcurrentHashMap<>();
172
173    private static Map<StringPair, LogWrapperBase> staticWrapperMap =
174            new ConcurrentHashMap<>();
175
176    protected MonitoringManager monitoringManager;
177
178    private static PresentationManager setupPresentationManager() {
179        staticWrapper = ORBUtilSystemException.get(
180            CORBALogDomains.RPC_PRESENTATION ) ;
181
182        boolean useDynamicStub = false;
183
184        PresentationManager.StubFactoryFactory dynamicStubFactoryFactory = null;
185
186        PresentationManager pm = new PresentationManagerImpl( useDynamicStub ) ;
187        pm.setStubFactoryFactory( false,
188            PresentationDefaults.getStaticStubFactoryFactory() ) ;
189        pm.setStubFactoryFactory( true, dynamicStubFactoryFactory ) ;
190        return pm;
191    }
192
193    public void destroy() {
194        wrapper = null;
195        omgWrapper = null;
196        typeCodeMap = null;
197        primitiveTypeCodeConstants = null;
198        byteBufferPool = null;
199    }
200
201    /**
202     * Returns the Presentation Manager for the current thread group, using the ThreadGroup-specific
203     * AppContext to hold it. Creates and records one if needed.
204     */
205    public static PresentationManager getPresentationManager()
206    {
207        SecurityManager sm = System.getSecurityManager();
208        JavaAWTAccess javaAwtAccess = SharedSecrets.getJavaAWTAccess();
209        if (sm != null && javaAwtAccess != null) {
210            final Object appletContext = javaAwtAccess.getAppletContext();
211            if (appletContext != null) {
212                return pmContexts.computeIfAbsent(appletContext,
213                    x -> setupPresentationManager());
214            }
215        }
216
217        // No security manager or AppletAppContext
218        return Holder.defaultPresentationManager;
219    }
220
221    /** Get the appropriate StubFactoryFactory.  This
222     * will be dynamic or static depending on whether
223     * com.sun.CORBA.ORBUseDynamicStub is true or false.
224     */
225    public static PresentationManager.StubFactoryFactory
226        getStubFactoryFactory()
227    {
228        PresentationManager gPM = getPresentationManager();
229        boolean useDynamicStubs = gPM.useDynamicStubs() ;
230        return gPM.getStubFactoryFactory( useDynamicStubs ) ;
231    }
232
233    protected ORB()
234    {
235        // Initialize logging first, since it is needed nearly
236        // everywhere (for example, in TypeCodeImpl).
237        wrapperMap = new ConcurrentHashMap<>();
238        wrapper = ORBUtilSystemException.get( this,
239            CORBALogDomains.RPC_PRESENTATION ) ;
240        omgWrapper = OMGSystemException.get( this,
241            CORBALogDomains.RPC_PRESENTATION ) ;
242
243        typeCodeMap = new HashMap<>();
244
245        primitiveTypeCodeConstants = new TypeCodeImpl[] {
246            new TypeCodeImpl(this, TCKind._tk_null),
247            new TypeCodeImpl(this, TCKind._tk_void),
248            new TypeCodeImpl(this, TCKind._tk_short),
249            new TypeCodeImpl(this, TCKind._tk_long),
250            new TypeCodeImpl(this, TCKind._tk_ushort),
251            new TypeCodeImpl(this, TCKind._tk_ulong),
252            new TypeCodeImpl(this, TCKind._tk_float),
253            new TypeCodeImpl(this, TCKind._tk_double),
254            new TypeCodeImpl(this, TCKind._tk_boolean),
255            new TypeCodeImpl(this, TCKind._tk_char),
256            new TypeCodeImpl(this, TCKind._tk_octet),
257            new TypeCodeImpl(this, TCKind._tk_any),
258            new TypeCodeImpl(this, TCKind._tk_TypeCode),
259            new TypeCodeImpl(this, TCKind._tk_Principal),
260            new TypeCodeImpl(this, TCKind._tk_objref),
261            null,       // tk_struct
262            null,       // tk_union
263            null,       // tk_enum
264            new TypeCodeImpl(this, TCKind._tk_string),
265            null,       // tk_sequence
266            null,       // tk_array
267            null,       // tk_alias
268            null,       // tk_except
269            new TypeCodeImpl(this, TCKind._tk_longlong),
270            new TypeCodeImpl(this, TCKind._tk_ulonglong),
271            new TypeCodeImpl(this, TCKind._tk_longdouble),
272            new TypeCodeImpl(this, TCKind._tk_wchar),
273            new TypeCodeImpl(this, TCKind._tk_wstring),
274            new TypeCodeImpl(this, TCKind._tk_fixed),
275            new TypeCodeImpl(this, TCKind._tk_value),
276            new TypeCodeImpl(this, TCKind._tk_value_box),
277            new TypeCodeImpl(this, TCKind._tk_native),
278            new TypeCodeImpl(this, TCKind._tk_abstract_interface)
279        } ;
280
281        monitoringManager =
282            MonitoringFactories.getMonitoringManagerFactory( ).
283                createMonitoringManager(
284                MonitoringConstants.DEFAULT_MONITORING_ROOT,
285                MonitoringConstants.DEFAULT_MONITORING_ROOT_DESCRIPTION);
286    }
287
288    // Typecode support: needed in both ORBImpl and ORBSingleton
289    public TypeCodeImpl get_primitive_tc(int kind)
290    {
291        synchronized (this) {
292            checkShutdownState();
293        }
294        try {
295            return primitiveTypeCodeConstants[kind] ;
296        } catch (Throwable t) {
297            throw wrapper.invalidTypecodeKind( t, new Integer(kind) ) ;
298        }
299    }
300
301    public synchronized void setTypeCode(String id, TypeCodeImpl code)
302    {
303        checkShutdownState();
304        typeCodeMap.put(id, code);
305    }
306
307    public synchronized TypeCodeImpl getTypeCode(String id)
308    {
309        checkShutdownState();
310        return typeCodeMap.get(id);
311    }
312
313    public MonitoringManager getMonitoringManager( ) {
314        synchronized (this) {
315            checkShutdownState();
316        }
317        return monitoringManager;
318    }
319
320    // Special non-standard set_parameters method for
321    // creating a precisely controlled ORB instance.
322    // An ORB created by this call is affected only by
323    // those properties passes explicitly in props, not by
324    // the system properties and orb.properties files as
325    // with the standard ORB.init methods.
326    public abstract void set_parameters( Properties props ) ;
327
328    // ORB versioning
329    public abstract ORBVersion getORBVersion() ;
330    public abstract void setORBVersion( ORBVersion version ) ;
331
332    // XXX This needs a better name
333    public abstract IOR getFVDCodeBaseIOR() ;
334
335    /**
336     * Handle a bad server id for the given object key.  This should
337     * always through an exception: either a ForwardException to
338     * allow another server to handle the request, or else an error
339     * indication.  XXX Remove after ORT for ORBD work is integrated.
340     */
341    public abstract void handleBadServerId( ObjectKey okey ) ;
342    public abstract void setBadServerIdHandler( BadServerIdHandler handler ) ;
343    public abstract void initBadServerIdHandler() ;
344
345    public abstract void notifyORB() ;
346
347    public abstract PIHandler getPIHandler() ;
348
349    public abstract void checkShutdownState();
350
351    // Dispatch support: in the ORB because it is needed for shutdown.
352    // This is used by the first level server side subcontract.
353    public abstract boolean isDuringDispatch() ;
354    public abstract void startingDispatch();
355    public abstract void finishedDispatch();
356
357    /** Return this ORB's transient server ID.  This is needed for
358     * initializing object adapters.
359     */
360    public abstract int getTransientServerId();
361
362    public abstract ServiceContextRegistry getServiceContextRegistry() ;
363
364    public abstract RequestDispatcherRegistry getRequestDispatcherRegistry();
365
366    public abstract ORBData getORBData() ;
367
368    public abstract void setClientDelegateFactory( ClientDelegateFactory factory ) ;
369
370    public abstract ClientDelegateFactory getClientDelegateFactory() ;
371
372    public abstract void setCorbaContactInfoListFactory( CorbaContactInfoListFactory factory ) ;
373
374    public abstract CorbaContactInfoListFactory getCorbaContactInfoListFactory() ;
375
376    // XXX These next 7 methods should be moved to a ResolverManager.
377
378    /** Set the resolver used in this ORB.  This resolver will be used for list_initial_services
379     * and resolve_initial_references.
380     */
381    public abstract void setResolver( Resolver resolver ) ;
382
383    /** Get the resolver used in this ORB.  This resolver will be used for list_initial_services
384     * and resolve_initial_references.
385     */
386    public abstract Resolver getResolver() ;
387
388    /** Set the LocalResolver used in this ORB.  This LocalResolver is used for
389     * register_initial_reference only.
390     */
391    public abstract void setLocalResolver( LocalResolver resolver ) ;
392
393    /** Get the LocalResolver used in this ORB.  This LocalResolver is used for
394     * register_initial_reference only.
395     */
396    public abstract LocalResolver getLocalResolver() ;
397
398    /** Set the operation used in string_to_object calls.  The Operation must expect a
399     * String and return an org.omg.CORBA.Object.
400     */
401    public abstract void setURLOperation( Operation stringToObject ) ;
402
403    /** Get the operation used in string_to_object calls.  The Operation must expect a
404     * String and return an org.omg.CORBA.Object.
405     */
406    public abstract Operation getURLOperation() ;
407
408    /** Set the ServerRequestDispatcher that should be used for handling INS requests.
409     */
410    public abstract void setINSDelegate( CorbaServerRequestDispatcher insDelegate ) ;
411
412    // XXX The next 5 operations should be moved to an IORManager.
413
414    /** Factory finders for the various parts of the IOR: tagged components, tagged
415     * profiles, and tagged profile templates.
416     */
417    public abstract TaggedComponentFactoryFinder getTaggedComponentFactoryFinder() ;
418    public abstract IdentifiableFactoryFinder getTaggedProfileFactoryFinder() ;
419    public abstract IdentifiableFactoryFinder getTaggedProfileTemplateFactoryFinder() ;
420
421    public abstract ObjectKeyFactory getObjectKeyFactory() ;
422    public abstract void setObjectKeyFactory( ObjectKeyFactory factory ) ;
423
424    // Logging SPI
425
426    /**
427     * Returns the logger based on the category.
428     */
429    public Logger getLogger( String domain )
430    {
431        synchronized (this) {
432            checkShutdownState();
433        }
434        ORBData odata = getORBData() ;
435
436        // Determine the correct ORBId.  There are 3 cases:
437        // 1. odata is null, which happens if we are getting a logger before
438        //    ORB initialization is complete.  In this case we cannot determine
439        //    the ORB ID (it's not known yet), so we set the ORBId to
440        //    _INITIALIZING_.
441        // 2. odata is not null, so initialization is complete, but ORBId is set to
442        //    the default "".  To avoid a ".." in
443        //    the log domain, we simply use _DEFAULT_ in this case.
444        // 3. odata is not null, ORBId is not "": just use the ORBId.
445        String ORBId ;
446        if (odata == null)
447            ORBId = "_INITIALIZING_" ;
448        else {
449            ORBId = odata.getORBId() ;
450            if (ORBId.equals(""))
451                ORBId = "_DEFAULT_" ;
452        }
453
454        return getCORBALogger( ORBId, domain ) ;
455    }
456
457    public static Logger staticGetLogger( String domain )
458    {
459        return getCORBALogger( "_CORBA_", domain ) ;
460    }
461
462    private static Logger getCORBALogger( String ORBId, String domain )
463    {
464        String fqLogDomain = CORBALogDomains.TOP_LEVEL_DOMAIN + "." +
465            ORBId + "." + domain;
466
467        return Logger.getLogger( fqLogDomain, ORBConstants.LOG_RESOURCE_FILE );
468    }
469
470    /** get the log wrapper class (its type is dependent on the exceptionGroup) for the
471     * given log domain and exception group in this ORB instance.
472     */
473    public LogWrapperBase getLogWrapper(String logDomain,
474        String exceptionGroup, LogWrapperFactory factory)
475    {
476        return wrapperMap.computeIfAbsent(
477            new StringPair(logDomain, exceptionGroup),
478            x -> factory.create(getLogger(logDomain)));
479    }
480
481    /** get the log wrapper class (its type is dependent on the exceptionGroup) for the
482     * given log domain and exception group in this ORB instance.
483     */
484    public static LogWrapperBase staticGetLogWrapper(String logDomain,
485        String exceptionGroup, LogWrapperFactory factory)
486    {
487        return staticWrapperMap.computeIfAbsent(
488            new StringPair(logDomain, exceptionGroup),
489            x -> factory.create(staticGetLogger(logDomain)));
490    }
491
492    // get a reference to a ByteBufferPool, a pool of NIO ByteBuffers
493    // NOTE: ByteBuffer pool must be unique per ORB, not per process.
494    //       There can be more than one ORB per process.
495    //       This method must also be inherited by both ORB and ORBSingleton.
496    public ByteBufferPool getByteBufferPool()
497    {
498        synchronized (this) {
499            checkShutdownState();
500        }
501        if (byteBufferPool == null)
502            byteBufferPool = new ByteBufferPoolImpl(this);
503
504        return byteBufferPool;
505    }
506
507    public abstract void setThreadPoolManager(ThreadPoolManager mgr);
508
509    public abstract ThreadPoolManager getThreadPoolManager();
510
511    public abstract CopierManager getCopierManager() ;
512}
513
514// End of file.
515