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