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