You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@avalon.apache.org by mc...@apache.org on 2002/08/13 05:57:57 UTC

cvs commit: jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/resource DefaultLifestyleManager.java LifestyleManager.java AbstractLifestyleHandler.java LifecycleHelper.java

mcconnell    2002/08/12 20:57:57

  Modified:    assembly/demo/src/java/org/apache/excalibur/playground
                        DemoManager.java DemoManager.xinfo
                        SimpleComponent.xinfo
               assembly/src/etc kernel.xml
               assembly/src/java/org/apache/excalibur/merlin/assembly
                        ContainerManager.java KernelManager.java
               assembly/src/java/org/apache/excalibur/merlin/container
                        ContainerFactory.java ContainerService.java
                        DefaultContainer.java DefaultContainer.xconfig
                        StructuralExtension.java StructuralExtension.xinfo
               assembly/src/java/org/apache/excalibur/merlin/kernel
                        DefaultKernel.java
               assembly/src/java/org/apache/excalibur/merlin/resource
                        AbstractLifestyleHandler.java LifecycleHelper.java
  Added:       assembly/src/java/org/apache/excalibur/merlin/resource
                        DefaultLifestyleManager.java LifestyleManager.java
  Log:
  Addition of pluggable lifestyle handlers via a LifestyleManager.  New interfaces
  and classes in the org.apache.excalibur.merlin.resource package provide
  support for kernel level declaration of a LifestyleManager implementation, and
  an initial DefaultLifestyleManager is included together with two implementations
  of the LifecycleHandler interface for singleton and transient policies. Current
  implementation approach set the lifestyle manager for the entire application,
  however, this should be easly extendible to have different LifestyleManagers
  at container levels.  Implementation currently provides support for manager
  inheritance down the container hierarchy.
  
  Revision  Changes    Path
  1.4       +6 -2      jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/DemoManager.java
  
  Index: DemoManager.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/DemoManager.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- DemoManager.java	12 Aug 2002 08:11:08 -0000	1.3
  +++ DemoManager.java	13 Aug 2002 03:57:56 -0000	1.4
  @@ -33,7 +33,8 @@
       {
           super.extend( stage, target, context );
           if( target instanceof Demonstratable )
  -          ((Demonstratable)target).demo( stageToString( stage ).toLowerCase() );
  +          ((Demonstratable)target).demo( stageToString( stage ).toLowerCase() 
  +             + ", instance: " + System.identityHashCode( this ) );
       }
   
       //=======================================================================
  @@ -42,7 +43,10 @@
   
       public void dispose()
       {
  -        getLogger().info( "dispose" );
  +        if( getLogger().isDebugEnabled() )
  +        {
  +            getLogger().debug( "dispose" );  
  +        }
       }
   
    }
  
  
  
  1.5       +5 -1      jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/DemoManager.xinfo
  
  Index: DemoManager.xinfo
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/DemoManager.xinfo,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- DemoManager.xinfo	12 Aug 2002 02:00:08 -0000	1.4
  +++ DemoManager.xinfo	13 Aug 2002 03:57:56 -0000	1.5
  @@ -1,13 +1,17 @@
   <?xml version="1.0"?>
   
   <!--
  -Definition of the extension type phase support.
  +Definition of the extension type phase support.  This demonstrates the 
  +use of a lifestyle policy inside an extension handler.
   -->
   
   <facility>
   
     <component>
       <name>demonstratable</name>
  +    <attributes>
  +      <attribute key="avalon:lifestyle" value="transient"/>
  +    </attributes>
     </component>
   
     <!--
  
  
  
  1.9       +0 -1      jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/SimpleComponent.xinfo
  
  Index: SimpleComponent.xinfo
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/SimpleComponent.xinfo,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- SimpleComponent.xinfo	5 Aug 2002 12:39:37 -0000	1.8
  +++ SimpleComponent.xinfo	13 Aug 2002 03:57:56 -0000	1.9
  @@ -36,7 +36,6 @@
     <phases>
        <phase>
           <reference type="org.apache.excalibur.playground.Exploitable" version="1.0"/>
  -        <attributes/>
        </phase>
        <phase>
           <reference type="org.apache.excalibur.playground.Demonstratable"/>
  
  
  
  1.33      +9 -1      jakarta-avalon-excalibur/assembly/src/etc/kernel.xml
  
  Index: kernel.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/etc/kernel.xml,v
  retrieving revision 1.32
  retrieving revision 1.33
  diff -u -r1.32 -r1.33
  --- kernel.xml	12 Aug 2002 20:34:33 -0000	1.32
  +++ kernel.xml	13 Aug 2002 03:57:56 -0000	1.33
  @@ -30,7 +30,7 @@
      </logging>
   
      <!--
  -   Declaration of installed extension directories.
  +   Declaration of installed extension directories and kernel level classpath.
      -->
   
      <extensions>
  @@ -44,6 +44,14 @@
          <include name="merlin.jar"/>
        </fileset>
      </classpath>
  +
  +   <!--
  +   Defintion of the lifestyle manager.
  +   The lifestyles class attribute must reference a class implementing the
  +   interface org.apache.excalibur.merlin.resource.LifestyleManager. 
  +   -->
  +
  +   <lifestyles class="org.apache.excalibur.merlin.resource.DefaultLifestyleManager"/>
   
      <!--
      Declaration of the root container.
  
  
  
  1.15      +131 -26   jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/ContainerManager.java
  
  Index: ContainerManager.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/ContainerManager.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- ContainerManager.java	12 Aug 2002 20:34:33 -0000	1.14
  +++ ContainerManager.java	13 Aug 2002 03:57:56 -0000	1.15
  @@ -39,6 +39,7 @@
   import org.apache.excalibur.merlin.container.Container;
   import org.apache.excalibur.merlin.container.DefaultContainer;
   import org.apache.excalibur.merlin.resource.LifestyleHandler;
  +import org.apache.excalibur.merlin.resource.LifestyleManager;
   import org.apache.excalibur.merlin.resource.SingletonLifestyleHandler;
   import org.apache.excalibur.merlin.resource.TransientLifestyleHandler;
   import org.apache.excalibur.merlin.resource.LifecycleHelper;
  @@ -97,6 +98,11 @@
       */
       public static final String CATEGORIES_DESCRIPTOR_KEY = "categories";
   
  +   /**
  +    * Context key used by the kernel to access the lifestyle manager.
  +    */
  +    public static final String LIFESTYLES_KEY = "lifestyles";
  +
       //===================================================================
       // state
       //===================================================================
  @@ -162,11 +168,16 @@
       private Hashtable m_resources = new Hashtable();
   
      /**
  -    * The dependency map.
  +    * The application dependency map.
       */
       private DependencyGraph m_map;
   
      /**
  +    * The system dependency map.
  +    */
  +    private DependencyGraph m_system;
  +
  +   /**
       * Utility class that we use to offload the management of profiles 
       * and which provides the actual assembly process.
       */
  @@ -192,10 +203,9 @@
       private DefaultLoggerManager m_logging;
   
      /**
  -    * The container model that contains the container's classpath declaration, 
  -    * explicit profile declarations, and defintions of the subsidiary containers.
  +    * The lifestyle manager.
       */
  -    private CategoriesDescriptor m_categories;
  +    private LifestyleManager m_lifestyles;
   
       //===================================================================
       // constructor
  @@ -215,11 +225,13 @@
           if( parent instanceof ContainerManager )
           {
               m_parent = (ContainerManager) parent;
  -            m_map = m_parent.getDependencyMap();
  +            m_map = m_parent.createApplicationMap();
  +            m_system = m_parent.createSystemMap();
           }
           else
           {
               m_map = new DependencyGraph();
  +            m_system= new DependencyGraph();
           }
   
           if( parent instanceof KernelManager )
  @@ -249,6 +261,14 @@
       {
           m_context = context;
           super.contextualize( context );
  +        try
  +        {
  +            m_lifestyles = (LifestyleManager) context.get( LIFESTYLES_KEY );
  +        }
  +        catch( ContextException e )
  +        {
  +            // optional
  +        }
       }
   
       //=======================================================================
  @@ -429,6 +449,10 @@
           // all of the component we are managing (see LifecycleHelper) - but
           // aside from that, we should be going though and cleaning up state 
           // locally 
  +
  +        logDependency( 
  +           getLogger(), "disassemble: ",  m_system.getShutdownGraph() 
  +        );
       }
   
       //===================================================================
  @@ -437,9 +461,13 @@
   
       public ContainerManager createContainerManager( 
                                    ContainerDescriptor descriptor,
  -                                 ClasspathDescriptor classpath )
  +                                 ClasspathDescriptor classpath,
  +                                 LifestyleManager lifestyles )
       {
   
  +        if( m_lifestyles == null )
  +          m_lifestyles = lifestyles;
  +
           //
           // bootstrap the creation of logging categories here because
           // logging will occur before the actual container is created
  @@ -469,6 +497,7 @@
               ContainerManager loader = new ContainerManager( this, name );
               DefaultContext context = new DefaultContext( m_context );
               context.put( TypeManager.CLASSPATH_DESCRIPTOR_KEY, classpath );
  +            context.put( LIFESTYLES_KEY, lifestyles );
   
               context.makeReadOnly();
               if( this instanceof KernelManager )
  @@ -519,6 +548,29 @@
       }
   
      /**
  +    * Return the lifestyle manager.  If a lifestyle manager is defined within the 
  +    * scope of this manager then return it otherwise return the parent's lifestyle 
  +    * manager.
  +    *
  +    * @return the lifestyle manager
  +    */
  +    protected LifestyleManager getLifestyleManager()
  +    {
  +        if( m_lifestyles != null )
  +          return m_lifestyles;
  +
  +        ContainerManager parent = getParentManager();
  +        if( parent != null )
  +        {
  +            return parent.getLifestyleManager();
  +        }
  +        else
  +        {
  +            throw new NullPointerException("lifestyles");
  +        }
  +    }
  +
  +   /**
       * Add a type profile to the manager.
       * 
       * @param profile the profile to add to the manager.
  @@ -739,42 +791,87 @@
       * @param the deployment context
       * @return a new resource 
       */
  -    private Resource createResource( Profile profile, Context context )
  +    private Resource createResource( Profile profile, Context context ) throws ResourceException
       {
           Resource resource = getLocalResource( profile );
           if( resource != null )
             return resource;
   
  -        // ######################################################################
  -        // ##                                                                   #
  -        // ## This is where we need to lookup a lifestyle policy handler and    #
  -        // ## assemble it before supplying it to the default resource instance. #
  -        // ##                                                                   #
  -        // ######################################################################
  +        try
  +        {
  +            LifestyleManager lifestyles = getLifestyleManager();
  +            LifestyleHandler handler =
  +              lifestyles.getHandler( this, m_helper, m_provider, profile, context );
  +            DefaultResource res = 
  +              new DefaultResource( getPath(), profile, context, handler );
  +            res.enableLogging( getLocalLogger().getChildLogger( "resource" ) );
  +            m_resources.put( profile, res );
  +            return res;
  +        }
  +        catch( Throwable e )
  +        {
  +            final String error =
  +              "Unexpected error while attempting to prepare a lifestyle handler.";
  +            throw new ResourceException( error, e );
  +        }
  +
  +/*
  +        LifestyleHandler handler;
   
  -        String policy = profile.getType().getInfo().getAttribute("avalon:lifestyle", "transient" );
  +        String policy = profile.getType().getInfo().getAttribute("avalon:lifestyle", "threadsafe" );
           if( policy.equals( "transient" ) )
           {
  +            handler = new TransientLifestyleHandler( 
  +              this, m_provider, m_helper, profile, context );
           }
  -        else if( policy.equalsIgnoreCase( "singleton" ) ) 
  +        else if( policy.equalsIgnoreCase( "threadsafe" ) ) 
           {
  +            handler = new SingletonLifestyleHandler( 
  +              this, m_provider, m_helper, profile, context );
           }
           else if( policy.equalsIgnoreCase( "per-thread" ) ) 
           {
  +            final String error = 
  +              "PerThread lifestyle policy in profile: '" 
  +              + getPath() + "/" + profile.getName()
  +              + "' unavailable.";
  +            throw new IllegalArgumentException( error );
           }
           else if( policy.equalsIgnoreCase( "pooled" ) ) 
           {
  +            final String error = 
  +              "Pooled lifestyle policy in profile: '" 
  +              + getPath() + "/" + profile.getName()
  +              + "' unavailable.";
  +            throw new IllegalArgumentException( error );
  +        }
  +        else if( policy.equalsIgnoreCase( "custom" ) ) 
  +        {
  +            String classname = profile.getType().getInfo().getAttribute("avalon:lifestyle.class");
  +
  +            final String error = 
  +              "Custom lifestyle policy in profile: '" 
  +              + getPath() + "/" + profile.getName()
  +              + "' for the class: '" + classname + "' not implemeted.";
  +            throw new IllegalArgumentException( error );
  +        }
  +        else
  +        {
  +            final String error =
  +              "Unrecognized lifestyle policy argument: '" + policy + "' in profile: '"
  +                + profile.getName();
  +            throw new IllegalArgumentException( error );
           }
   
  -        SingletonLifestyleHandler handler = 
  -           new SingletonLifestyleHandler( this, m_provider, m_helper, profile, context );
  -        handler.enableLogging( getLocalLogger().getChildLogger("lifestyle") );
  +        if( handler instanceof LogEnabled )
  +          ((LogEnabled)handler).enableLogging( getLocalLogger().getChildLogger("lifestyle") );
   
           DefaultResource designator = 
             new DefaultResource( getPath(), profile, context, handler );
           designator.enableLogging( getLocalLogger().getChildLogger( "resource" ) );
           m_resources.put( profile, designator );
           return designator;
  +*/
       }
   
      /**
  @@ -788,17 +885,15 @@
       */
       public Resource assemble( Profile profile, Context context ) throws AssemblyException
       {
  -        DependencyGraph map = new DependencyGraph( m_map );
  -        Resource resource = m_registry.assembleProfile( map, profile, context );
  +        Resource resource = m_registry.assembleProfile( m_system, profile, context );
           logDependency( 
              getLocalLogger(), 
  -           "bootstrap-assembly: (" + profile.getName() + "): ",  
  -           map.getStartupGraph() 
  +           "system: (" + profile.getName() + "): ",  
  +           m_system.getStartupGraph() 
           );
           return resource;
       }
   
  -
      /**
       * Assemble a profile into a consistent application.  This method 
       * attempts to establish associations between all dependencies in order to 
  @@ -895,13 +990,23 @@
       }
   
      /**
  -    * Returns a child dependency graph.
  +    * Returns a child dependency graph for the application scope.
       * @return a new dependency graph
       */
  -    protected DependencyGraph getDependencyMap()
  +    protected DependencyGraph createApplicationMap()
       {
           return new DependencyGraph( m_map );
       }
  +
  +   /**
  +    * Returns a child dependency graph for the system scope.
  +    * @return a new dependency graph
  +    */
  +    protected DependencyGraph createSystemMap()
  +    {
  +        return new DependencyGraph( m_system );
  +    }
  +
   
      /**
       * Returns the set of exportable resources.
  
  
  
  1.3       +3 -1      jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/KernelManager.java
  
  Index: KernelManager.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/KernelManager.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- KernelManager.java	12 Aug 2002 02:00:09 -0000	1.2
  +++ KernelManager.java	13 Aug 2002 03:57:56 -0000	1.3
  @@ -12,6 +12,7 @@
   import org.apache.avalon.excalibur.i18n.Resources;
   import org.apache.avalon.framework.context.Context;
   import org.apache.avalon.framework.context.ContextException;
  +import org.apache.excalibur.merlin.resource.LifestyleManager;
   
   
   /**
  @@ -37,6 +38,7 @@
       * Context key used by the kernel to access the kernel meta-data descriptor.
       */
       public static final String LOGGING_KEY = "logging";
  +
   
       //===================================================================
       // state
  
  
  
  1.2       +27 -3     jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/ContainerFactory.java
  
  Index: ContainerFactory.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/ContainerFactory.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ContainerFactory.java	12 Aug 2002 01:55:44 -0000	1.1
  +++ ContainerFactory.java	13 Aug 2002 03:57:56 -0000	1.2
  @@ -70,6 +70,7 @@
   import org.apache.excalibur.merlin.assembly.ContainerManager;
   import org.apache.excalibur.merlin.assembly.DefaultLoggerManager;
   import org.apache.excalibur.merlin.assembly.DependencyGraph;
  +import org.apache.excalibur.merlin.resource.LifestyleManager;
   import org.apache.excalibur.merlin.model.ContainerDescriptor;
   import org.apache.excalibur.merlin.model.ClasspathDescriptor;
   import org.apache.excalibur.merlin.model.Profile;
  @@ -118,6 +119,11 @@
       */
       private DefaultLoggerManager m_logging;
   
  +   /**
  +    * The logging manager to pass to the created container.
  +    */
  +    private LifestyleManager m_lifestyles;
  +
       //=======================================================================
       // constructor
       //=======================================================================
  @@ -134,6 +140,22 @@
                           DefaultLoggerManager logging )
          
       {
  +        this( manager, logging, null );
  +    }
  +
  +   /**
  +    * Creation of a container factory that supports the creation of 
  +    * subsidiary containers.
  +    *
  +    * @param manager the context type manager
  +    * @param logging the logging manager
  +    */
  +    public ContainerFactory( 
  +                        ContainerManager manager, 
  +                        DefaultLoggerManager logging,
  +                        LifestyleManager lifestyles )
  +       
  +    {
           if( manager == null )
             throw new NullPointerException("manager");
   
  @@ -142,6 +164,7 @@
   
           m_manager = manager;
           m_logging = logging;
  +        m_lifestyles = lifestyles;
       }
   
      /**
  @@ -164,7 +187,8 @@
             throw new NullPointerException( "classpath" );
   
           final ContainerManager manager = 
  -          m_manager.createContainerManager( descriptor, classpath );
  +          m_manager.createContainerManager( descriptor, classpath, m_lifestyles );
  +
           return new ContainerService( m_logging, descriptor, manager, new Hashtable() );
       }
   
  @@ -205,7 +229,7 @@
                 m_creator.createClasspathDescriptor( config.getChild("classpath") );
   
               final ContainerManager manager = 
  -              m_manager.createContainerManager( descriptor, classpath );
  +              m_manager.createContainerManager( descriptor, classpath, m_lifestyles );
   
               //
               // populate the descriptor with component profiles
  
  
  
  1.3       +1 -6      jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/ContainerService.java
  
  Index: ContainerService.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/ContainerService.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ContainerService.java	12 Aug 2002 17:36:16 -0000	1.2
  +++ ContainerService.java	13 Aug 2002 03:57:56 -0000	1.3
  @@ -163,9 +163,4 @@
               throw new AssemblyException( error, e );
           }
       }
  -
  -    //ContainerService getService( ContainerDescriptor key )
  -    //{
  -    //    return (ContainerService) m_services.get( key );
  -    //}
   }
  
  
  
  1.32      +1 -32     jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/DefaultContainer.java
  
  Index: DefaultContainer.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/DefaultContainer.java,v
  retrieving revision 1.31
  retrieving revision 1.32
  diff -u -r1.31 -r1.32
  --- DefaultContainer.java	12 Aug 2002 17:36:16 -0000	1.31
  +++ DefaultContainer.java	13 Aug 2002 03:57:56 -0000	1.32
  @@ -1108,35 +1108,4 @@
               return true;
           }
       }
  -
  -    private void logDependency( Logger logger, String lead, Profile[] result )
  -    {
  -        if( logger.isInfoEnabled() )
  -        {
  -            if( result.length > 0 )
  -            {
  -                StringBuffer buffer = new StringBuffer();
  -                for( int i=0; i<result.length; i++ )
  -                {
  -                    Profile profile = result[i];
  -                    if( m_manager.isLocal( profile ) )
  -                    {
  -                        buffer.append( result[i].getName() );
  -                    }
  -                    else
  -                    {
  -                        buffer.append( "[" + result[i].getName() + "]" );
  -                    }
  -                    if( i<(result.length-1) )
  -                      buffer.append(", ");
  -                }
  -                logger.info( lead + buffer.toString() );
  -            }
  -            else
  -            {
  -                logger.info( lead + "(empty)" );
  -            }
  -        }
  -    }
  -
   }
  
  
  
  1.2       +0 -5      jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/DefaultContainer.xconfig
  
  Index: DefaultContainer.xconfig
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/DefaultContainer.xconfig,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- DefaultContainer.xconfig	8 Aug 2002 09:59:47 -0000	1.1
  +++ DefaultContainer.xconfig	13 Aug 2002 03:57:56 -0000	1.2
  @@ -12,10 +12,5 @@
   
   <configuration>
   
  -   <!--
  -   The execution element defines execution constraints 
  -   and policies for the container.
  -   -->
  -   <execution mode="asynchronous"/>
   
   </configuration>
  
  
  
  1.3       +0 -14     jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/StructuralExtension.java
  
  Index: StructuralExtension.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/StructuralExtension.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- StructuralExtension.java	12 Aug 2002 08:11:09 -0000	1.2
  +++ StructuralExtension.java	13 Aug 2002 03:57:56 -0000	1.3
  @@ -3,19 +3,7 @@
   package org.apache.excalibur.merlin.container;
   
   import org.apache.avalon.framework.context.Context;
  -import org.apache.avalon.framework.logger.AbstractLogEnabled;
  -import org.apache.avalon.framework.context.ContextException;
  -import org.apache.avalon.framework.configuration.Configuration;
  -import org.apache.excalibur.merlin.assembly.TypeException;
  -import org.apache.excalibur.merlin.assembly.ContainerManager;
  -import org.apache.excalibur.merlin.container.Container;
  -import org.apache.excalibur.merlin.container.Structural;
  -import org.apache.excalibur.merlin.resource.Extension;
   import org.apache.excalibur.merlin.resource.AbstractExtension;
  -import org.apache.excalibur.merlin.model.builder.XMLContainerUtil;
  -import org.apache.excalibur.merlin.model.ContainerDescriptor;
  -import org.apache.excalibur.merlin.model.Profile;
  -import org.apache.excalibur.meta.info.Type;
   
   /**
    * Extension that supplorts the assembly of a container structure.
  @@ -23,8 +11,6 @@
    */
   public class StructuralExtension extends AbstractExtension
   {
  -
  -    private XMLContainerUtil m_creator = new XMLContainerUtil();
   
       //=======================================================================
       // Extension
  
  
  
  1.2       +3 -11     jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/StructuralExtension.xinfo
  
  Index: StructuralExtension.xinfo
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/StructuralExtension.xinfo,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- StructuralExtension.xinfo	12 Aug 2002 01:56:37 -0000	1.1
  +++ StructuralExtension.xinfo	13 Aug 2002 03:57:56 -0000	1.2
  @@ -8,6 +8,9 @@
   
     <component>
       <name>structural</name>
  +    <attributes>
  +      <attribute key="avalon:lifestyle" value="singleton"/>
  +    </attributes>
     </component>
   
     <extensions>
  @@ -16,17 +19,6 @@
   
         <name>assemble</name>
         <reference type="org.apache.excalibur.merlin.container.Structural"/>
  -
  -      <!--
  -      <context>
  -        <entry key="merlin:container.descriptor" 
  -          type="org.apache.excalibur.merlin.model.ContainerDescriptor" />
  -        <entry key="merlin:container.manager"
  -          type="org.apache.excalibur.merlin.assembly.ContainerManager"/>
  -        <entry key="merlin:container.configuration"
  -          type="org.apache.avalon.framework.configuration.Configuration"/>
  -      </context>
  -      -->
   
       </extension>
   
  
  
  
  1.36      +35 -5     jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/DefaultKernel.java
  
  Index: DefaultKernel.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/DefaultKernel.java,v
  retrieving revision 1.35
  retrieving revision 1.36
  diff -u -r1.35 -r1.36
  --- DefaultKernel.java	12 Aug 2002 06:08:54 -0000	1.35
  +++ DefaultKernel.java	13 Aug 2002 03:57:56 -0000	1.36
  @@ -31,6 +31,7 @@
   import org.apache.excalibur.configuration.ConfigurationUtil;
   import org.apache.avalon.framework.CascadingRuntimeException;
   import org.apache.avalon.framework.logger.Logger;
  +import org.apache.avalon.framework.logger.LogEnabled;
   import org.apache.avalon.framework.logger.AbstractLogEnabled;
   import org.apache.avalon.framework.logger.AvalonFormatter;
   import org.apache.avalon.framework.logger.LogKitLogger;
  @@ -59,6 +60,7 @@
   import org.apache.avalon.excalibur.extension.OptionalPackage;
   import org.apache.avalon.excalibur.extension.DefaultPackageRepository;
   import org.apache.avalon.excalibur.logger.LoggerManager;
  +import org.apache.excalibur.configuration.ConfigurationUtil;
   import org.apache.excalibur.meta.info.Type;
   import org.apache.excalibur.meta.info.ServiceDescriptor;
   import org.apache.excalibur.meta.info.DependencyDescriptor;
  @@ -76,20 +78,20 @@
   import org.apache.excalibur.merlin.model.ContainerDescriptor;
   import org.apache.excalibur.merlin.model.ContextDirective;
   import org.apache.excalibur.merlin.model.Resource;
  +import org.apache.excalibur.merlin.model.builder.XMLContainerUtil;
  +import org.apache.excalibur.merlin.model.LoggingDescriptor;
   import org.apache.excalibur.merlin.assembly.TypeManager;
   import org.apache.excalibur.merlin.assembly.TypeException;
   import org.apache.excalibur.merlin.assembly.ContainerManager;
   import org.apache.excalibur.merlin.assembly.KernelManager;
   import org.apache.excalibur.merlin.assembly.DefaultLoggerManager;
  -import org.apache.excalibur.merlin.model.builder.XMLContainerUtil;
  -import org.apache.excalibur.merlin.model.LoggingDescriptor;
   import org.apache.excalibur.merlin.container.Container;
   import org.apache.excalibur.merlin.container.DefaultContainer;
   import org.apache.excalibur.merlin.container.ContainerService;
   import org.apache.excalibur.merlin.container.StateListener;
   import org.apache.excalibur.merlin.container.StateEvent;
   import org.apache.excalibur.merlin.container.ContainerFactory;
  -import org.apache.excalibur.configuration.ConfigurationUtil;
  +import org.apache.excalibur.merlin.resource.LifestyleManager;
   
   /**
    * Default kernel implementation.
  @@ -342,11 +344,38 @@
               Thread.currentThread().setContextClassLoader( m_manager );
               getLogger().info("kernel established: " + name );
   
  +            //
  +            // Create the lifestyle manager.
  +            //
  +
  +            LifestyleManager lifestyles;
  +            try
  +            {
  +                Configuration lifestyleConfig = m_config.getChild("lifestyles");
  +                String lifestyleClassname = lifestyleConfig.getAttribute(
  +                  "class","org.apache.excalibur.merlin.resource.DefaultLifestyleManager");
  +                Class clazz = m_manager.loadClass( lifestyleClassname );
  +                lifestyles = (LifestyleManager) clazz.newInstance();
  +                if( lifestyles instanceof LogEnabled )
  +                  ((LogEnabled)lifestyles).enableLogging( 
  +                     getLogger().getChildLogger("lifestyles") );
  +                if( lifestyles instanceof Configurable )
  +                  ((Configurable)lifestyles).configure( lifestyleConfig );
  +                if( lifestyles instanceof Initializable )
  +                  ((Initializable)lifestyles).initialize();
  +            }
  +            catch( Throwable e )
  +            {
  +                final String error = "Lifestyle manager establishment failure.";
  +                throw new KernelException( error, e );
  +            }
  +
               // 
               // setup the root container
               //
   
  -            ContainerFactory factory = new ContainerFactory( m_manager, getLoggingManager() );
  +            ContainerFactory factory = 
  +              new ContainerFactory( m_manager, getLoggingManager(), lifestyles );
               factory.enableLogging( m_logger );
   
               ContainerService service = factory.build( config );
  @@ -465,6 +494,7 @@
           {
               ((Disposable)m_container).dispose();
           }
  +        m_manager.dispose();
       }
   
       //=======================================================================
  
  
  
  1.3       +1 -0      jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/resource/AbstractLifestyleHandler.java
  
  Index: AbstractLifestyleHandler.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/resource/AbstractLifestyleHandler.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- AbstractLifestyleHandler.java	12 Aug 2002 17:36:16 -0000	1.2
  +++ AbstractLifestyleHandler.java	13 Aug 2002 03:57:56 -0000	1.3
  @@ -136,6 +136,7 @@
               try
               {
                   extension.extend( stage, object, context );
  +                resource.release( extension );
               }
               catch( Throwable e )
               {
  
  
  
  1.3       +2 -0      jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/resource/LifecycleHelper.java
  
  Index: LifecycleHelper.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/resource/LifecycleHelper.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- LifecycleHelper.java	12 Aug 2002 17:36:16 -0000	1.2
  +++ LifecycleHelper.java	13 Aug 2002 03:57:56 -0000	1.3
  @@ -189,6 +189,7 @@
                           getLogger().info("applying phase " + phase.getReference() + " to " + path );
                           Context extContext = provider.createContext( ext, phaseContext );
                           extension.extend( Extension.CREATE, object, extContext );
  +                        resource.release( extension );
                       }
                       catch( Throwable e )
                       {
  @@ -294,6 +295,7 @@
                       getLogger().info("applying '" + phase.getReference() 
                         + "' to '" + name + "'.");
                       extension.extend( Extension.DESTROY, object, new DefaultContext() );
  +                    resource.release( extension );
                   }
                   catch( Throwable e )
                   {
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/resource/DefaultLifestyleManager.java
  
  Index: DefaultLifestyleManager.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.TXT file.
   *
   * Original contribution by OSM SARL, http://www.osm.net
   */
  package org.apache.excalibur.merlin.resource;
  
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.avalon.framework.context.Context;
  import org.apache.avalon.framework.configuration.Configurable;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.activity.Initializable;
  import org.apache.excalibur.merlin.assembly.ContainerManager;
  import org.apache.excalibur.merlin.model.Profile;
  
  /**
   * Utility class that handles the establishment of an appropriate lifestyle 
   * handler based on a supplied profile. 
   *
   * @author <a href="mailto:mcconnell@osm.net">Stephen McConnell</a>
   */
  public class DefaultLifestyleManager extends AbstractLogEnabled 
  implements LifestyleManager, Configurable, Initializable
  {
  
       private Configuration m_config;
  
       public void configure( Configuration config )
       {
           m_config = config;
       }
  
       public void initialize() throws Exception
       {
       }
  
      /**
       * <p>Returns a lifestyle handler implementation based on a supplied 
       * profile.  The implementation recognizes the following lifestyle
       * policy declarations supplied as values against the component 
       * attribute <strong>avalon:lifestyle</strong>:</p>
       *
       * <table>
       *  <tr><td><p>policy</p></td><td><p>description</p></td></tr>
       *  <tr><td><p>singleton</p></td><td>
       *    <p>single service instance is sharable across mutiple 
       *       instances operating in different threads</p></td></tr>
       *  <tr><td><p>thread</p></td><td>
       *    <p>a new service instance is establied under the first request 
       *       within the scope of a particular thread.  The instance is 
       *       subsequently shared across mutiple instances within the 
       *       scope of a particular thread</p></td></tr>
       *  <tr><td><p>pooled</p></td><td>
       *    <p>service instaces are maintainer in a pool and recycled 
       *       by the lifestyle handler</p></td></tr>
       *  <tr><td><p>transient</p></td><td>
       *    <p>new instances are created per request</p></td></tr>
       *  <tr><td><p>custom</p></td><td>
       *    <p>the handler policy is defined by a custom implementation
       *       class declared under the attribute key 
       *       <strong>avalon:lifestyle.class</strong></p></td></tr>
       * </table>
       *
       *
       * @param manager the container type manager
       * @param helper a lifecycle helper
       * @param provider a resource provider
       * @param profile the profies containing the lifestyle policy
       *
       * @return a lifecycle handler supporting the requested policy
       * @exception Exception if an error occurs during handler establishment
       */
       public LifestyleHandler getHandler( 
                              ContainerManager manager, 
                              LifecycleHelper helper, 
                              ResourceProvider provider, 
                              Profile profile, 
                              Context context ) 
       throws Exception
       {
  
          final String policy = 
            profile.getType().getInfo().getAttribute("avalon:lifestyle", "singleton" );
  
          if( policy.equalsIgnoreCase( "singleton" ) ) 
          {
              //
              // create a thread safe lifestyle handler
              //
  
              SingletonLifestyleHandler handler = 
                new SingletonLifestyleHandler( manager, provider, helper, profile, context );
              handler.enableLogging( getLogger() );
              return handler;
          }
          else if( policy.equals( "transient" ) )
          {
              //
              // create a transient lifestyle handler
              //
  
              TransientLifestyleHandler handler = 
                new TransientLifestyleHandler( manager, provider, helper, profile, context );
              handler.enableLogging( getLogger() );
              return handler;
          }
          else if( policy.equalsIgnoreCase( "thread" ) ) 
          {
              //
              // per-thread lifestyle handler not implemented
              //
  
              final String error = 
                "PerThread lifestyle policy in profile: '" 
                + manager.getPath() + "/" + profile.getName()
                + "' unavailable.";
              throw new IllegalArgumentException( error );
          }
          else if( policy.equalsIgnoreCase( "pooled" ) ) 
          {
              //
              // pooled lifestyle handler not implemented
              //
  
              final String error = 
                "Pooled lifestyle policy in profile: '" 
                + manager.getPath() + "/" + profile.getName()
                + "' unavailable.";
              throw new IllegalArgumentException( error );
          }
          else
          {
              final String error =
                "Unrecognized lifestyle policy argument: '" + policy + "' in profile: '"
                  + manager.getPath() + "/" + profile.getName();
              throw new IllegalArgumentException( error );
          }
       }
  }
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/resource/LifestyleManager.java
  
  Index: LifestyleManager.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.TXT file.
   *
   * Original contribution by OSM SARL, http://www.osm.net
   */
  package org.apache.excalibur.merlin.resource;
  
  import org.apache.avalon.framework.context.Context;
  import org.apache.avalon.framework.configuration.Configurable;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.activity.Initializable;
  import org.apache.excalibur.merlin.model.Profile;
  import org.apache.excalibur.merlin.assembly.ContainerManager;
  
  /**
   * Utility class that handles the establishment of an appropriate lifestyle 
   * handler based on a supplied profile. 
   *
   * @author <a href="mailto:mcconnell@osm.net">Stephen McConnell</a>
   */
  public interface LifestyleManager
  {
  
      /**
       * <p>Returns a lifestyle handler implementation based on a supplied 
       * profile.  The implementation recognizes the following lifestyle
       * policy declarations supplied as values against the component 
       * attribute <strong>avalon:lifestyle</strong>:</p>
       *
       * <p><strong>Lifestyle Policy Value Table</strong></p>
       * <table cellspacing="3">
       *  <tr><td><p><strong>policy</strong></p></td><td><p><strong>description</strong></p></td></tr>
       *  <tr><td><p><code>singleton</code></p></td><td>
       *    <p>single service instance is sharable across mutiple 
       *       instances operating in different threads</p></td></tr>
       *  <tr><td><p><code>thread</code></p></td><td>
       *    <p>a new service instance is establied under the first request 
       *       within the scope of a particular thread.  The instance is 
       *       subsequently shared across mutiple instances within the 
       *       scope of a particular thread</p></td></tr>
       *  <tr><td><p><code>pooled</code></p></td><td>
       *    <p>service instaces are maintainer in a pool and recycled 
       *       by the lifestyle handler</p></td></tr>
       *  <tr><td><p><code>transient</code></p></td><td>
       *    <p>new instances are created per request</p></td></tr>
       * </table>
       *
       * <p><strong>XML</strong></p>
       * <pre>
       *   <font color="gray">&lt;--
       *   The following kernel defintion includes the declaration of a custom
       *   lifestyle manager that will be associated with the root container 
       *   and will handle resolution of lifestyle handlers relative to supplied 
       *   profiles.
       *   --&gt;</font>
       *
       *   &lt;kernel&gt;
       *
       *     &lt;lifestyles class="<font color="darkred">MyLifestyleManager</font>"&gt;
       *
       *       <font color="gray">&lt;--
       *       Any configuration delcarations included here 
       *       will be supplied to the lifestyle manager instance as a
       *       configuration (if the class implements Configurable).
       *       --&gt;</font>
       *
       *     &lt;/lifestyles"&gt;
       *
       *   &lt;kernel&gt;
       * </pre>
       *
       * @param manager the container type manager
       * @param helper a lifecycle helper
       * @param provider a resource provider
       * @param profile the profies containing the lifestyle policy
       *
       * @return a lifecycle handler supporting the requested policy
       * @exception Exception if an error occurs during handler establishment
       * @see DefaultLifestyleManager
       */
       public LifestyleHandler getHandler( 
                              ContainerManager manager, 
                              LifecycleHelper helper, 
                              ResourceProvider provider, 
                              Profile profile, 
                              Context context ) 
       throws Exception;
  
  }
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>