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