avalon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Anton Tagunov <atagu...@mail.cnt.ru>
Subject [Patch] #10.1 Part II
Date Thu, 29 May 2003 08:29:29 GMT
Hello Berin!

This patch hopefully completes my patching series
on Fortress. This is the second and last part of
the #10.1 that used to be pending for a while.

This patch

1.===================InstrumentManager stuff===

isolates the change in the LifecycleExtensionManager
done by the container from the LifecycleExtensionManager
possibly passed in for the "master".

This patch stops testing if an InstrumentableCreator is
already in the LifecycleExtensionManager: indeed we want
_our_ instrumentManager to be engaged not just any
instrumentManager. Hence we always add a new InstrumentableCreator.

As I write in the code comments, we assume that there is none
InstrumentableCreator already in the LifecycleExtensionManager
if we receive any because otherwise we will get double
invocation of setInstrumentManager which is probably a bug.

Abstract container might even test that there is _none_
InstrumentableCreator in the LifecycleExtensionManager, but
I haven't written this because I consider that anyone can
write another CreatorExtension, with a different class but
doing the same -- invoking setInstrumentManager.

So I think it is better to safeguard our components in
some other way: test that an instrumentManager is not
assigned twice to us if it really makes us uset.

So I do not test this in the code proposed.

2. =============================================

provideComponentContext method is added to allow
derived containers control what context is passed
to the compnents they create, the default just
returns m_context.

3. =============================================

provideServiceMethod is an override point that
allowes derived contianers to optionally block
part of services available from the parent
service manager - and otherwise change
the serviceManager creation procedure

4. =============================================
excluded RoleManager from @avalon.dependecy on
service()

---------------

BTW, ContextManagerTestCase has started outputting a lot
of stuff to the console when invoked. The current CVS
state (without my latest #12, #10.1 parts I and II)
behaves the same.

- WBR, Anton

--- AbstractContainer.orig      2003-05-29 09:59:26.000000000 +0400
+++ AbstractContainer.java      2003-05-29 12:21:12.000000000 +0400
@@ -126,6 +126,12 @@
     /** contains the impl's LifecycleExtensionManager, which is extracted from m_serviceManager.
*/
     protected LifecycleExtensionManager m_extManager;
     /**
+     * contains the context that will be passed to the components we will create.  
+     * initialized the first time a component handler is created by a call to
+     * provideComponentContext -- override this method to affect the value of this object.
+     */
+    protected Context m_componentContext;
+    /**
      * Contains entries mapping roles to hint maps, where the hint map contains
      * mappings from hints to ComponentHandlers.
      */
@@ -172,7 +178,6 @@
      * @avalon.dependency type="PoolManager"
      * @avalon.dependency type="InstrumentManager"
      * @avalon.dependency type="LifecycleExtensionManager" optional="true"
-     * @avalon.dependency type="RoleManager" optional="true"
      * @avalon.dependency type="Sink" optional="true"
      */
     public void service( final ServiceManager serviceManager )
@@ -203,7 +208,7 @@
         m_metaManager = (MetaInfoManager) serviceManager.lookup( MetaInfoManager.ROLE );
 
         // set up our ServiceManager
-        m_serviceManager = new FortressServiceManager( this, serviceManager );
+        m_serviceManager = provideServiceManager( serviceManager );
     }
 
     /**
@@ -217,45 +222,49 @@
         final Logger extLogger = m_loggerManager.getLoggerForCategory( "system.extensions"
);
         if ( serviceManager.hasService( LifecycleExtensionManager.ROLE ) )
         {
-            m_extManager =
-                (LifecycleExtensionManager) serviceManager.lookup( LifecycleExtensionManager.ROLE
);
-
-            extLogger.debug( "Found the LifecycleExtensionManager" );
-        }
-        else
-        {
-            m_extManager = new LifecycleExtensionManager();
-            m_extManager.enableLogging( extLogger );
-            m_extManager.addCreatorExtension( new InstrumentableCreator( m_instrumentManager
) );
+            final LifecycleExtensionManager parent = (LifecycleExtensionManager)
+                    serviceManager.lookup( LifecycleExtensionManager.ROLE );
 
-            if ( getLogger().isDebugEnabled() )
+            if ( extLogger.isDebugEnabled() )
             {
-                final String message =
-                    "No Container.LIFECYCLE_EXTENSION_MANAGER is given, " +
-                    "installing default lifecycle extension manager with " +
-                    "1 extensions";
-                getLogger().debug( message );
+                final String message = "Found the LifecycleExtensionManager, creating a copy.";
+                extLogger.debug( message );
             }
-        }
 
-        /* Add all the standard extensions if they have not already been
-         * done.
-         */
-        boolean isInstrumentEnabled = false;
-        final Iterator it = m_extManager.creatorExtensionsIterator();
-        while ( it.hasNext() )
+            m_extManager = parent.writeableCopy();
+        }
+        else
         {
-            if ( it.next() instanceof InstrumentableCreator )
+            if ( extLogger.isDebugEnabled() )
             {
-                isInstrumentEnabled = true;
+                final String message = "No LifecycleExtensionManager found, creating a new
one.";
+                extLogger.debug( message );
             }
+            m_extManager = new LifecycleExtensionManager();
         }
 
-        if ( !isInstrumentEnabled )
+        /** LifecycleExtensionManager.writeableCopy() does not copy the logger. */
+        m_extManager.enableLogging( extLogger );
+
+        if ( extLogger.isDebugEnabled() )
         {
-            extLogger.debug("No Instrumentable Creator was found.  We are adding a new one.");
-            m_extManager.addCreatorExtension( new InstrumentableCreator( m_instrumentManager
) );
-        }
+            final String message = 
+                    "Adding an InstrumentableCreator to support our InstrumentManager";
+            extLogger.debug( message );
+        }
+
+        /**
+         * We do need a new InstrumentableCreator, as we want strictly our
+         * m_instrumentManager to be engaged. We assume there is no 
+         * InstrumentableCreator in the LifecycleExtensionManager passed to us 
+         * already. If there is one this is probably a bug. Not testing this currently, 
+         * although might test this in the future in order to
+         * throw something like an IllegalArgumentException.
+         */
+        m_extManager.addCreatorExtension( new InstrumentableCreator( m_instrumentManager
) );
+
+        // just to be on the safe side
+        m_extManager.makeReadOnly();
     }
 
     /**
@@ -415,10 +424,19 @@
                                                  final Configuration configuration )
         throws Exception
     {
+        if ( m_componentContext == null )
+        {
+            m_componentContext = provideComponentContext( m_context );
+            if ( m_componentContext == null )
+            {
+                throw new IllegalStateException( "provideComponentContext() has returned
null" );
+            }
+        }
+
         final Class clazz = m_classLoader.loadClass( classname );
         final ComponentFactory componentFactory =
             new ComponentFactory( clazz, configuration,
-                m_serviceManager, m_context,
+                m_serviceManager, m_componentContext,
                 m_loggerManager, m_extManager );
         return m_proxyManager.getWrappedObjectFactory( componentFactory );
     }
@@ -763,4 +781,43 @@
     {
         return m_serviceManager;
     }
+
+    /**
+     * Override this method to control creation of the serviceManager
+     * belonging to this container. This serviceManager is passed to
+     * child components as they are being created and is exposed via
+     * the getServiceManager() method.
+     * Invoked from the service() method.
+     *
+     * However even a self-contained container should be carefull about
+     * cutting access to parent serviceManager completely, as important 
+     * (and required) system services including Sink, LoggerManager, 
+     * InstrumentManager, PoolManager and LifecycleExtensionManager 
+     * are passed via ServiceManager also. SourceResolver hangs somewhere
+     * in between system and "user space" services.
+     *
+     * It's more or less okay to cut access to them if our child
+     * components do not need them and are not containers themselves,
+     * but if we have containers as our children they will require these
+     * services.
+     */
+    protected ServiceManager provideServiceManager( final ServiceManager parent ) 
+            throws Exception
+    {
+        return new FortressServiceManager( this, parent );
+    }
+
+    /**
+     * Override this method to control what context will be passed to
+     * the components created by this container. Called the first time
+     * a component being created - withing this implementation it is
+     * a part of the configure() stage.
+     * You may derive your context from m_context or create a new one.
+     */
+    protected Context provideComponentContext( final Context parent ) 
+            throws Exception
+    {
+        /* the default implementation: just use the same as for container itself */
+        return parent;
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@avalon.apache.org
For additional commands, e-mail: dev-help@avalon.apache.org


Mime
View raw message