You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@avalon.apache.org by bl...@apache.org on 2001/04/05 21:38:45 UTC

cvs commit: jakarta-avalon/src/java/org/apache/avalon/util/pool AbstractPool.java

bloritsch    01/04/05 12:38:45

  Modified:    .        build.bat build.xml
               proposal/4.0/src/java/org/apache/avalon/pool
                        AbstractPool.java DefaultObjectFactory.java
                        DefaultPool.java ObjectFactory.java
               proposal/4.0/src/java/org/apache/avalon/thread
                        DefaultThreadPool.java ThreadContext.java
                        ThreadManager.java WorkerThread.java
               proposal/4.0/src/java/org/apache/framework/component
                        DefaultComponentManager.java
                        DefaultComponentSelector.java
               proposal/4.0/src/java/org/apache/framework/configuration
                        AbstractConfiguration.java Configurable.java
                        Configuration.java ConfigurationException.java
                        DefaultConfiguration.java
                        DefaultConfigurationBuilder.java Parameters.java
                        Reconfigurable.java SAXConfigurationHandler.java
               src/java/org/apache/avalon/camelot/pipeline
                        StartupPipeline.java
               src/java/org/apache/avalon/util/pool AbstractPool.java
  Log:
  Many fixes to 4.0 tree, and backporting Cocoon's ComponentManagement
  Infrastructure.
  
  Revision  Changes    Path
  1.4       +1 -1      jakarta-avalon/build.bat
  
  Index: build.bat
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/build.bat,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- build.bat	2001/04/02 06:50:49	1.3
  +++ build.bat	2001/04/05 19:38:41	1.4
  @@ -7,7 +7,7 @@
   set ANT_HOME=tools
   
   set CP=%CLASSPATH%
  -set CLASSPATH=lib\xerces.jar
  +set CLASSPATH=lib\xerces.jar;lib\oracle.jar
   
   :runAnt
   %ANT_HOME%\bin\ant.bat -logger org.apache.tools.ant.NoBannerLogger -emacs %1 %2 %3 %4 %5 %6 %7 %8
  
  
  
  1.26      +6 -0      jakarta-avalon/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/build.xml,v
  retrieving revision 1.25
  retrieving revision 1.26
  diff -u -r1.25 -r1.26
  --- build.xml	2001/04/02 07:36:59	1.25
  +++ build.xml	2001/04/05 19:38:41	1.26
  @@ -185,6 +185,12 @@
          ===================================================================
     -->
     <target name="prepare" depends="check-environment,setup-properties">
  +    <available property="jndi.present" classname="javax.naming.Context">
  +      <classpath refid="project.class.path"/>
  +    </available>
  +    <available property="datasource.present" classname="javax.sql.DataSource">
  +      <classpath refid="project.class.path"/>
  +    </available>
       <tstamp/>
       <mkdir dir="${build.dir}"/>
   
  
  
  
  1.5       +78 -99    jakarta-avalon/proposal/4.0/src/java/org/apache/avalon/pool/AbstractPool.java
  
  Index: AbstractPool.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/proposal/4.0/src/java/org/apache/avalon/pool/AbstractPool.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- AbstractPool.java	2001/04/02 04:06:30	1.4
  +++ AbstractPool.java	2001/04/05 19:38:41	1.5
  @@ -7,7 +7,12 @@
    */
   package org.apache.avalon.pool;
   
  +import java.util.Vector;
  +import java.util.Stack;
  +
   import org.apache.framework.lifecycle.Initializable;
  +import org.apache.framework.logger.AbstractLoggable;
  +import org.apache.framework.thread.ThreadSafe;
   
   /**
    * This is an <code>Pool</code> that caches Poolable objects for reuse.
  @@ -17,141 +22,115 @@
    * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
    */
   public class AbstractPool
  -    implements Pool, Initializable
  +    extends AbstractLoggable
  +    implements Pool, ThreadSafe
   {
  -    protected int                     m_count;
  -    protected Poolable[]              m_pool;
  -    protected ObjectFactory           m_factory;
  -    protected PoolController          m_controller;
  -    protected int                     m_maximum;
  -    protected int                     m_initial;
  +    protected final ObjectFactory  m_factory;
  +    protected final int            m_min;
  +    protected int                  m_max;
  +    protected int                  m_currentCount  = 0;
  +    protected Vector               m_active        = new Vector();
  +    protected Stack                m_ready         = new Stack();
   
  +    /**
  +     * Create an AbstractPool.  The pool requires a factory, and can
  +     * optionally have a controller.
  +     */
       public AbstractPool( final ObjectFactory factory,
  -                         final PoolController controller,
  -                         final int initial,
  -                         final int maximum )
  +                         final int min,
  +                         final int max ) throws Exception
       {
  -        m_count = 0;
           m_factory = factory;
  -        m_controller = controller;
  -        m_maximum = maximum;
  -        m_initial = initial;
  -    }
  +        int t_max = max;
  +        int t_min = min;
   
  -    public void init() 
  -        throws Exception
  -    {
  -        grow( m_maximum );
  -        fill( m_initial );
  -    }
  -
  -    /**
  -     * Retrieve an object from pool.
  -     *
  -     * @return an object from Pool
  -     */
  -    public Poolable get() throws Exception
  -    {
  -        if( null == m_pool && null != m_controller )
  +        if( min < 0 )
           {
  -            final int increase = m_controller.grow();
  -            if( increase > 0 ) grow( increase );
  -        }
  +            if( null != getLogger() )
  +            {
  +                getLogger().warn( "Minumum number of poolables specified is " +
  +                                  "less than 0, using 0" );
  +            }
   
  -        if( 0 == m_count )
  +            t_min = 0;
  +        }
  +        else
           {
  -            return m_factory.newInstance();
  +            t_min = min;
           }
  -
  -        m_count--;
   
  -        final Poolable poolable = m_pool[ m_count ];
  -        m_pool[ m_count ] = null;
  -        return poolable;
  -    }
  -
  -    /**
  -     * Place an object in pool.
  -     *
  -     * @param poolable the object to be placed in pool
  -     */
  -    public void put( final Poolable poolable )
  -    {
  -        if( poolable instanceof Recyclable )
  +        if( ( max < min ) || ( max < 1 ) )
           {
  -            ((Recyclable)poolable).recycle();
  +            if( null != getLogger() )
  +            {
  +                getLogger().warn( "Maximum number of poolables specified must be at " +
  +                                  "least 1 and must be greater than the minumum number " +
  +                                  "of connections" );
  +            }
  +            t_max = ( min > 1 ) ? min : 1;
           }
  -
  -        if(  m_pool.length == (m_count + 1) && null != m_controller )
  +        else
           {
  -            final int decrease = m_controller.shrink();
  -            if( decrease > 0 ) shrink( decrease );
  +            t_max = max;
           }
   
  -        if ( m_pool.length > m_count + 1 )
  +        m_max = t_max;
  +        m_min = t_min;
  +
  +        if( !(this instanceof Initializable) )
           {
  -            m_pool[ m_count++ ] = poolable;
  +            init();
           }
       }
   
  -    /**
  -     * Return the total number of slots in Pool
  -     *
  -     * @return the total number of slots
  -     */
  -    public final int getCapacity()
  +    protected void init()
  +        throws Exception
       {
  -        return m_pool.length;
  +        for( int i = 0; i < m_min; i++ )
  +        {
  +            m_ready.push( m_factory.newInstance() );
  +            m_currentCount++;
  +        }
       }
   
  -    /**
  -     * Get the number of used slots in Pool
  -     *
  -     * @return the number of used slots
  -     */
  -    public final int getSize()
  -    {
  -        return m_count;
  +    public int size() {
  +        int count = this.m_currentCount;
  +        return count;
       }
   
  -    /**
  -     * This fills the pool to the size specified in parameter.
  -     */
  -    public final void fill( final int fillSize ) throws Exception
  +    public synchronized Poolable get()
  +        throws Exception
       {
  -        final int size = Math.min( m_pool.length, fillSize );
  +        Poolable obj = null;
   
  -        for( int i = m_count; i < size; i++ )
  +        if( 0 == m_ready.size() )
           {
  -            m_pool[i] = m_factory.newInstance();
  +            obj = (Poolable)m_factory.newInstance();
  +            m_currentCount++;
           }
  +        else
  +        {
  +            obj = (Poolable)m_ready.pop();
  +        }
   
  -        m_count = size;
  -    }
  +        m_active.addElement( obj );
   
  -    /**
  -     * This fills the pool by the size specified in parameter.
  -     */
  -    public final void grow( final int increase )
  -    {
  -        if( null == m_pool )
  +        if( null != getLogger() )
           {
  -            m_pool = new Poolable[ increase ];
  -            return;
  +            getLogger().debug( m_factory.getCreatedClass().getName() + ": requested from the pool." );
           }
   
  -        final Poolable[] poolables = new Poolable[ increase + m_pool.length ];
  -        System.arraycopy( m_pool, 0, poolables, 0, m_pool.length );
  -        m_pool = poolables;
  +        return obj;
       }
   
  -    /**
  -     * This shrinks the pool by parameter size.
  -     */
  -    public final void shrink( final int decrease )
  +    public synchronized void put( final Poolable obj )
       {
  -        final Poolable[] poolables = new Poolable[ m_pool.length - decrease ];
  -        System.arraycopy( m_pool, 0, poolables, 0, poolables.length );
  -        m_pool = poolables;
  +        m_active.removeElement( obj );
  +        m_ready.push( obj );
  +
  +        if( null != getLogger() )
  +        {
  +            getLogger().debug( m_factory.getCreatedClass().getName() + ": returned to the pool." );
  +        }
       }
   }
  
  
  
  1.4       +11 -6     jakarta-avalon/proposal/4.0/src/java/org/apache/avalon/pool/DefaultObjectFactory.java
  
  Index: DefaultObjectFactory.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/proposal/4.0/src/java/org/apache/avalon/pool/DefaultObjectFactory.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- DefaultObjectFactory.java	2001/04/02 04:06:30	1.3
  +++ DefaultObjectFactory.java	2001/04/05 19:38:41	1.4
  @@ -30,8 +30,8 @@
           m_constructor = constructor;
       }
   
  -    public DefaultObjectFactory( final Class clazz, 
  -                                 final Class[] arguementClasses, 
  +    public DefaultObjectFactory( final Class clazz,
  +                                 final Class[] arguementClasses,
                                    final Object[] arguements )
           throws NoSuchMethodException
       {
  @@ -49,16 +49,21 @@
           return m_constructor.getDeclaringClass();
       }
   
  -    public Poolable newInstance()
  +    public Object newInstance()
       {
           try
           {
               return (Poolable)m_constructor.newInstance( m_arguements );
  -        } 
  -        catch( final Exception e ) 
  +        }
  +        catch( final Exception e )
           {
  -            throw new Error( "Failed to instantiate the class " + 
  +            throw new Error( "Failed to instantiate the class " +
                                m_constructor.getDeclaringClass().getName() + " due to " + e );
           }
  +    }
  +
  +    public void decommission(Object object)
  +    {
  +       object = null;
       }
   }
  
  
  
  1.4       +6 -6      jakarta-avalon/proposal/4.0/src/java/org/apache/avalon/pool/DefaultPool.java
  
  Index: DefaultPool.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/proposal/4.0/src/java/org/apache/avalon/pool/DefaultPool.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- DefaultPool.java	2001/04/02 04:06:30	1.3
  +++ DefaultPool.java	2001/04/05 19:38:41	1.4
  @@ -15,30 +15,30 @@
    * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
    */
   public class DefaultPool
  -    extends AbstractPool
  +    extends SingleThreadedPool
   {
       public final static int           DEFAULT_POOL_SIZE           = 8;
   
  -    public DefaultPool( final ObjectFactory factory, 
  -                        final PoolController controller ) 
  +    public DefaultPool( final ObjectFactory factory,
  +                        final PoolController controller )
           throws Exception
       {
           super( factory, controller, DEFAULT_POOL_SIZE, DEFAULT_POOL_SIZE );
       }
   
  -    public DefaultPool( final ObjectFactory factory ) 
  +    public DefaultPool( final ObjectFactory factory )
           throws Exception
       {
           this( factory, null );
       }
   
  -    public DefaultPool( final Class clazz, final int initial, final int maximum ) 
  +    public DefaultPool( final Class clazz, final int initial, final int maximum )
           throws NoSuchMethodException, Exception
       {
           super( new DefaultObjectFactory( clazz ), null, initial, maximum );
       }
   
  -    public DefaultPool( final Class clazz, final int initial ) 
  +    public DefaultPool( final Class clazz, final int initial )
           throws NoSuchMethodException, Exception
       {
           this( clazz, initial, initial );
  
  
  
  1.5       +6 -2      jakarta-avalon/proposal/4.0/src/java/org/apache/avalon/pool/ObjectFactory.java
  
  Index: ObjectFactory.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/proposal/4.0/src/java/org/apache/avalon/pool/ObjectFactory.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- ObjectFactory.java	2001/04/02 04:06:30	1.4
  +++ ObjectFactory.java	2001/04/05 19:38:41	1.5
  @@ -7,6 +7,8 @@
    */
   package org.apache.avalon.pool;
   
  +import org.apache.framework.component.Component;
  +
   /**
    * This is the interface for factory that is used to create objects for Pool.
    *
  @@ -14,8 +16,10 @@
    * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
    * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
    */
  -public interface ObjectFactory 
  +public interface ObjectFactory
  +    extends Component
   {
  -    Poolable newInstance() throws Exception;
  +    Object newInstance() throws Exception;
       Class getCreatedClass();
  +    void decommission(Object object) throws Exception;
   }
  
  
  
  1.5       +6 -7      jakarta-avalon/proposal/4.0/src/java/org/apache/avalon/thread/DefaultThreadPool.java
  
  Index: DefaultThreadPool.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/proposal/4.0/src/java/org/apache/avalon/thread/DefaultThreadPool.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- DefaultThreadPool.java	2001/04/03 23:18:01	1.4
  +++ DefaultThreadPool.java	2001/04/05 19:38:42	1.5
  @@ -8,10 +8,9 @@
   package org.apache.avalon.thread;
   
   import org.apache.framework.logger.Loggable;
  -import org.apache.avalon.pool.ObjectFactory;
   import org.apache.avalon.pool.Poolable;
  -import org.apache.avalon.pool.ThreadSafePool;
  -import org.apache.avalon.thread.ThreadPool;
  +import org.apache.avalon.pool.ObjectFactory;
  +import org.apache.avalon.pool.SoftResourceLimitingPool;
   import org.apache.log.Logger;
   
   /**
  @@ -26,7 +25,7 @@
       extends ThreadGroup
       implements ObjectFactory, Loggable, ThreadPool
   {
  -    protected final ThreadSafePool            m_pool;
  +    protected final SoftResourceLimitingPool  m_pool;
       protected int                             m_level;
       protected Logger                          m_logger;
   
  @@ -40,7 +39,7 @@
           throws Exception
       {
           super( name );
  -        m_pool = new ThreadSafePool( this, 0 );
  +        m_pool = new SoftResourceLimitingPool( this, 0 );
           m_pool.init();
       }
   
  @@ -49,7 +48,7 @@
           m_logger = logger;
       }
   
  -    public Poolable newInstance()
  +    public Object newInstance()
       {
           final WorkerThread worker =
               new WorkerThread( this, this, m_pool, getName() + " Worker #" + m_level++ );
  @@ -58,7 +57,7 @@
           return worker;
       }
   
  -    public void decommission(Poolable object) 
  +    public void decommission( final Object object )
       {
           if( object instanceof WorkerThread )
           {
  
  
  
  1.5       +24 -3     jakarta-avalon/proposal/4.0/src/java/org/apache/avalon/thread/ThreadContext.java
  
  Index: ThreadContext.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/proposal/4.0/src/java/org/apache/avalon/thread/ThreadContext.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- ThreadContext.java	2001/04/03 23:18:01	1.4
  +++ ThreadContext.java	2001/04/05 19:38:42	1.5
  @@ -12,18 +12,39 @@
    *
    * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
    */
  -public final class ThreadContext 
  +public final class ThreadContext
   {
  -    protected final static InheritableThreadLocal   c_context = new InheritableThreadLocal();
  +    private final static RuntimePermission      c_permission =
  +        new RuntimePermission( "ThreadContext.setCurrentThreadPool" );
  +    private final static InheritableThreadLocal c_context    = new InheritableThreadLocal();
   
  +    /**
  +     * Retrieve thread pool associated with current thread
  +     *
  +     * @return a thread pool
  +     */
       public static ThreadPool getCurrentThreadPool()
       {
           return (ThreadPool)c_context.get();
       }
   
  +    /**
  +     * Set the thread pool that will be returned by getCurrentThreadPool() in this thread
  +     * and decendent threads.
  +     *
  +     * @param threadPool the new thread pool
  +     * @exception SecurityException if the caller does not have permission to set thread pool
  +     */
       public static void setCurrentThreadPool( final ThreadPool threadPool )
  +        throws SecurityException
       {
  -        //TODO: protect by a permission guard
  +        final SecurityManager securityManager = System.getSecurityManager();
  +
  +        if( null != securityManager )
  +        {
  +            securityManager.checkPermission( c_permission );
  +        }
  +
           c_context.set( threadPool );
       }
   }
  
  
  
  1.5       +3 -0      jakarta-avalon/proposal/4.0/src/java/org/apache/avalon/thread/ThreadManager.java
  
  Index: ThreadManager.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/proposal/4.0/src/java/org/apache/avalon/thread/ThreadManager.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- ThreadManager.java	2001/04/03 23:18:01	1.4
  +++ ThreadManager.java	2001/04/05 19:38:42	1.5
  @@ -7,6 +7,8 @@
    */
   package org.apache.avalon.thread;
   
  +import org.apache.framework.component.Component;
  +
   /**
    * Interface for component that hands out thread pools.
    *
  @@ -14,6 +16,7 @@
    * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
    */
   public interface ThreadManager
  +    extends Component
   {
       ThreadPool getThreadPool( String name );
       ThreadPool getDefaultThreadPool();
  
  
  
  1.8       +4 -6      jakarta-avalon/proposal/4.0/src/java/org/apache/avalon/thread/WorkerThread.java
  
  Index: WorkerThread.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/proposal/4.0/src/java/org/apache/avalon/thread/WorkerThread.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- WorkerThread.java	2001/04/03 23:18:01	1.7
  +++ WorkerThread.java	2001/04/05 19:38:42	1.8
  @@ -7,11 +7,9 @@
    */
   package org.apache.avalon.thread;
   
  -import org.apache.avalon.pool.Poolable;
  -import org.apache.avalon.pool.ThreadSafePool;
   import org.apache.framework.logger.Loggable;
  -import org.apache.avalon.thread.ThreadContext;
  -import org.apache.avalon.thread.ThreadPool;
  +import org.apache.avalon.pool.Poolable;
  +import org.apache.avalon.pool.SoftResourceLimitingPool;
   import org.apache.log.Logger;
   
   /**
  @@ -28,7 +26,7 @@
   
       protected Logger                    m_logger;
       protected ThreadPool                m_threadPool;
  -    protected ThreadSafePool            m_pool;
  +    protected SoftResourceLimitingPool  m_pool;
   
       protected Runnable                  m_work;
       protected boolean                   m_alive;
  @@ -38,7 +36,7 @@
        */
       protected WorkerThread( final ThreadGroup group,
                               final ThreadPool threadPool,
  -                            final ThreadSafePool pool,
  +                            final SoftResourceLimitingPool pool,
                               final String name )
       {
           super( group, name );
  
  
  
  1.2       +229 -55   jakarta-avalon/proposal/4.0/src/java/org/apache/framework/component/DefaultComponentManager.java
  
  Index: DefaultComponentManager.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/proposal/4.0/src/java/org/apache/framework/component/DefaultComponentManager.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- DefaultComponentManager.java	2001/04/03 23:18:02	1.1
  +++ DefaultComponentManager.java	2001/04/05 19:38:43	1.2
  @@ -1,82 +1,256 @@
  -/*
  - * 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 file.
  - */
  +/*****************************************************************************
  + * 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 file.                                                         *
  + *****************************************************************************/
  +
   package org.apache.framework.component;
   
   import java.util.HashMap;
  +import java.util.Map;
  +import java.util.Collections;
   import java.util.Iterator;
  +import java.util.ArrayList;
  +import java.util.List;
   
  +import org.apache.framework.context.Context;
  +import org.apache.framework.context.Contextualizable;
  +import org.apache.framework.configuration.Configurable;
  +import org.apache.framework.configuration.Configuration;
  +import org.apache.framework.configuration.ConfigurationException;
  +import org.apache.framework.configuration.DefaultConfiguration;
  +import org.apache.framework.lifecycle.Disposable;
  +import org.apache.framework.lifecycle.Initializable;
  +import org.apache.framework.logger.AbstractLoggable;
  +
   /**
  - * This class is a static implementation of a ComponentManager. Allow ineritance
  - * and extention so you can generate a tree of ComponentManager each defining
  - * Component scope.
  + * Default component manager for Avalon's components.
    *
  - * @author <a href="mailto:scoobie@pop.systemy.it">Federico Barbieri</a>
  - * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
  + * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
  + * @author <a href="mailto:paul@luminas.co.uk">Paul Russell</a>
  + * @version CVS $Revision: 1.2 $ $Date: 2001/04/05 19:38:43 $
    */
  -public class DefaultComponentManager
  -    implements ComponentManager
  -{
  -    protected final HashMap               m_components = new HashMap();
  -    protected final ComponentManager      m_parent;
  +public class DefaultComponentManager extends AbstractLoggable
  +        implements ComponentManager, Configurable, Contextualizable, Disposable {
   
  -    public DefaultComponentManager()
  -    {
  -        this( null );
  +    /** The application context for components
  +     */
  +    private Context context;
  +
  +    /** Static component mapping handlers.
  +     */
  +    private Map componentMapping;
  +
  +    /** Static component handlers.
  +     */
  +    private Map componentHandlers;
  +
  +    /** RoleInfos.
  +     */
  +    private RoleInfo roles;
  +
  +    /** Is the Manager disposed or not? */
  +    private boolean disposed = false;
  +
  +    /** Construct a new default component manager.
  +     */
  +    public DefaultComponentManager() {
  +        // Setup the maps.
  +        componentHandlers = Collections.synchronizedMap(new HashMap());
  +        componentMapping = Collections.synchronizedMap(new HashMap());
       }
   
  -    public DefaultComponentManager( final ComponentManager parent )
  -    {
  -        m_parent = parent;
  +    /** Set up the Component's Context.
  +     */
  +    public void contextualize(Context context) {
  +        if (this.context == null) {
  +            this.context = context;
  +        }
       }
   
  -    public Component lookup( final String role )
  -        throws ComponentException
  -    {
  -        final Component component = (Component)m_components.get( role );
  +    /** Properly dispose of the Child handlers.
  +     */
  +    public synchronized void dispose() {
  +        this.disposed = true;
  +
  +        Iterator keys = this.componentHandlers.keySet().iterator();
  +        List keyList = new ArrayList();
  +
  +        while (keys.hasNext()) {
  +            Object key = keys.next();
  +            DefaultComponentHandler handler = (DefaultComponentHandler)
  +                this.componentHandlers.get(key);
   
  -        if( null != component )
  -        {
  -            return component;
  +            handler.dispose();
  +            keyList.add(key);
           }
  -        else if( null != m_parent )
  -        {
  -            return m_parent.lookup( role );
  +
  +        keys = keyList.iterator();
  +
  +        while (keys.hasNext()) {
  +            this.componentHandlers.remove(keys.next());
           }
  -        else
  -        {
  -            throw new ComponentException("Unable to provide implementation for " + role);
  +
  +        keyList.clear();
  +    }
  +
  +    /**
  +     * Return an instance of a component based on a Role.  The Role is usually the Interface's
  +     * Fully Qualified Name(FQN)--unless there are multiple Components for the same Role.  In that
  +     * case, the Role's FQN is appended with "Selector", and we return a ComponentSelector.
  +     */
  +    public Component lookup( String role )
  +    throws ComponentException {
  +
  +        if (disposed) throw new IllegalStateException("You cannot lookup components on a disposed ComponentManager");
  +
  +        DefaultComponentHandler handler = null;
  +        Component component = null;
  +
  +        if ( role == null ) {
  +            getLogger().error("ComponentManager Attempted to retrieve component with null role.");
  +            throw new ComponentException("Attempted to retrieve component with null role.");
           }
  +
  +        handler = (DefaultComponentHandler) this.componentHandlers.get(role);
  +        // Retrieve the instance of the requested component
  +        if ( handler == null ) {
  +            getLogger().debug("Could not find ComponentHandler, attempting to create one for role: " + role);
  +            Class componentClass = null;
  +            Configuration config = new DefaultConfiguration("", "-");
  +
  +            try {
  +                componentClass = this.getClass().getClassLoader().loadClass(roles.defaultClass(role));
  +
  +                handler = new DefaultComponentHandler(componentClass, config, this, this.context);
  +                handler.setLogger(getLogger());
  +                handler.init();
  +            } catch (Exception e) {
  +                getLogger().error("ComponentManager Could not find component for role: " + role, e);
  +                throw new ComponentException("Could not find component for role: " + role, e);
  +            }
  +
  +            this.componentHandlers.put(role, handler);
  +        }
  +
  +        try {
  +            component = handler.get();
  +        } catch (IllegalStateException ise) {
  +            handler.init();
  +
  +            try {
  +                component = handler.get();
  +            } catch (Exception ee) {
  +                throw new ComponentException("Could not access the Component for you", ee);
  +            }
  +        } catch (Exception e) {
  +            throw new ComponentException("Could not access the Component for you", e);
  +        }
  +
  +        this.componentMapping.put(component, handler);
  +        return component;
       }
   
  -    public void put( final String name, final Component component )
  -    {
  -        m_components.put( name, component );
  +    /**
  +     * Configure the ComponentManager.
  +     */
  +    public void configure(Configuration conf) throws ConfigurationException {
  +        DefaultRoleInfo role_info = new DefaultRoleInfo();
  +        role_info.setLogger(getLogger());
  +        role_info.configure(conf);
  +        roles = role_info;
  +
  +        // Set components
  +
  +        Configuration[] e = conf.getChildren("component");
  +        for (int i = 0; i < e.length; i++) {
  +            String type = e[i].getAttribute("type", "");
  +            String role = e[i].getAttribute("role", "");
  +            String className = e[i].getAttribute("class", "");
  +
  +            if (! "".equals(type)) {
  +                role = roles.lookup(type);
  +            }
  +
  +            if ("".equals(className)) {
  +                className = roles.defaultClass(role);
  +            }
  +
  +            try {
  +                getLogger().debug("Adding component (" + role + " = " + className + ")");
  +                this.addComponent(role, this.getClass().getClassLoader().loadClass(className),e[i]);
  +            } catch ( Exception ex ) {
  +                getLogger().error("Could not load class " + className, ex);
  +                throw new ConfigurationException("Could not get class " + className
  +                    + " for role " + role, ex);
  +            }
  +        }
  +
  +        Iterator r = roles.shorthandNames();
  +        while (r.hasNext()) {
  +            Configuration co = conf.getChild((String) r.next(), false);
  +
  +            if (co != null) {
  +                String role = roles.lookup(co.getName());
  +                String className = co.getAttribute("class", "");
  +
  +                if ("".equals(className)) {
  +                    className = roles.defaultClass(role);
  +                }
  +
  +                try {
  +                    getLogger().debug("Adding component (" + role + " = " + className + ")");
  +                    this.addComponent(role, this.getClass().getClassLoader().loadClass(className), co);
  +                } catch ( Exception ex ) {
  +                    getLogger().error("Could not load class " + className, ex);
  +                    throw new ConfigurationException("Could not get class " + className
  +                        + " for role " + role, ex);
  +                }
  +            }
  +        }
       }
   
  -    public void release( final Component component )
  -    {
  -        // if the ComponentManager handled pooling, it would be
  -        // returned to the pool here.
  +    /**
  +     * Release a Component.  This implementation makes sure it has a handle on the propper
  +     * ComponentHandler, and let's the ComponentHandler take care of the actual work.
  +     */
  +    public void release(Component component) {
  +        if (component == null) return;
  +        DefaultComponentHandler handler = (DefaultComponentHandler) this.componentMapping.get(component);
  +        if (handler == null) return;
  +        handler.put(component);
  +        this.componentMapping.remove(component);
       }
   
  -    public String toString() 
  -    {
  -        final StringBuffer buffer = new StringBuffer();
  -        final Iterator components = m_components.keySet().iterator();
  -        buffer.append( "Components:" );
  +    /** Add a new component to the manager.
  +     * @param role the role name for the new component.
  +     * @param component the class of this component.
  +     * @param Configuration the configuration for this component.
  +     */
  +    public void addComponent(String role, Class component, Configuration config)
  +    throws ComponentException {
  +        try {
  +            DefaultComponentHandler handler = new DefaultComponentHandler(component, config, this, this.context);
  +            handler.setLogger(getLogger());
  +            this.componentHandlers.put(role, handler);
  +        } catch (Exception e) {
  +            throw new ComponentException ("Could not set up Component for role: " + role, e);
  +        }
  +    }
   
  -        while( components.hasNext() )
  -        {
  -            buffer.append( "[" );
  -            buffer.append( components.next() );
  -            buffer.append( "]" );
  +    /** Add a static instance of a component to the manager.
  +     * @param role the role name for the component.
  +     * @param instance the instance of the component.
  +     */
  +    public void addComponentInstance(String role, Object instance) {
  +        try {
  +            DefaultComponentHandler handler = new DefaultComponentHandler((Component) instance);
  +            handler.setLogger(getLogger());
  +            this.componentHandlers.put(role, handler);
  +        } catch (Exception e) {
  +            getLogger().warn("Could not set up Component for role: " + role, e);
           }
  -        
  -        return buffer.toString();
       }
   }
  
  
  
  1.2       +249 -28   jakarta-avalon/proposal/4.0/src/java/org/apache/framework/component/DefaultComponentSelector.java
  
  Index: DefaultComponentSelector.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/proposal/4.0/src/java/org/apache/framework/component/DefaultComponentSelector.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- DefaultComponentSelector.java	2001/04/03 23:18:02	1.1
  +++ DefaultComponentSelector.java	2001/04/05 19:38:43	1.2
  @@ -1,52 +1,273 @@
  -/*
  - * 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 file.
  - */
  +/*****************************************************************************
  + * 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 file.                                                         *
  + *****************************************************************************/
  +
   package org.apache.framework.component;
   
   import java.util.HashMap;
  +import java.util.Map;
  +import java.util.Collections;
  +import java.util.Iterator;
  +import java.util.ArrayList;
  +import java.util.List;
   
  +import org.apache.framework.context.Context;
  +import org.apache.framework.context.Contextualizable;
  +import org.apache.framework.configuration.Configurable;
  +import org.apache.framework.configuration.Configuration;
  +import org.apache.framework.configuration.ConfigurationException;
  +import org.apache.framework.configuration.DefaultConfiguration;
  +import org.apache.framework.logger.AbstractLoggable;
  +import org.apache.framework.lifecycle.Disposable;
  +import org.apache.framework.thread.ThreadSafe;
  +
   /**
  - * This is the default implementation of the ComponentSelector
  + * Default component manager for Avalon's components.
  + *
  + * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
  + * @author <a href="mailto:paul@luminas.co.uk">Paul Russell</a>
  + * @version CVS $Revision: 1.2 $ $Date: 2001/04/05 19:38:43 $
    */
  -public class DefaultComponentSelector implements ComponentSelector {
  +public class DefaultComponentSelector extends AbstractLoggable implements Contextualizable, ComponentSelector, Composer, Configurable, ThreadSafe, Disposable {
  +
  +    /** The application context for components
  +     */
  +    protected Context context;
  +
  +    /** The application context for components
  +     */
  +    private ComponentManager manager;
  +
  +    /** Dynamic component handlers mapping.
  +     */
  +    private Map componentMapping;
  +
  +    /** Static configuraiton object.
  +     */
  +    private Configuration conf = null;
  +
  +    /** Static component handlers.
  +     */
  +    private Map componentHandlers;
   
  -    protected final HashMap components = new HashMap();
  +    /** Flag for if this is disposed or not.
  +     */
  +    private boolean disposed = false;
  +
  +    /** Shorthand for hints
  +     */
  +    private Map hints;
   
  +    /** Construct a new default component manager.
  +     */
       public DefaultComponentSelector() {
  -        // do nothing
  +        // Setup the maps.
  +        componentHandlers = Collections.synchronizedMap(new HashMap());
  +        componentMapping = Collections.synchronizedMap(new HashMap());
       }
   
  +    /** Provide the application Context.
  +     */
  +    public void contextualize(Context context) {
  +        if (this.context == null) {
  +            this.context = context;
  +        }
  +    }
  +
  +    /** Compose the ComponentSelector so that we know what the parent ComponentManager is.
  +     */
  +    public void compose(ComponentManager manager) throws ComponentException {
  +        if (this.manager == null) {
  +            this.manager = manager;
  +        }
  +    }
  +
       /**
  -     * Select the desired component.  It does not cascade, neither
  -     * should it.
  +     * Properly dispose of all the ComponentHandlers.
        */
  -    public Component select(Object hint)
  -        throws ComponentException {
  +    public synchronized void dispose() {
  +        this.disposed = true;
  +
  +        Iterator keys = this.componentHandlers.keySet().iterator();
  +        List keyList = new ArrayList();
   
  -        final Component component = (Component) components.get(hint);
  +        while (keys.hasNext()) {
  +            Object key = keys.next();
  +            DefaultComponentHandler handler = (DefaultComponentHandler)
  +                this.componentHandlers.get(key);
   
  -        if ( component != null ) {
  -            return component;
  -        } else {
  -            throw new ComponentException( "Unable to provide implementation for " + 
  -                                          hint.toString() );
  +            handler.dispose();
  +            keyList.add(key);
           }
  +
  +        keys = keyList.iterator();
  +
  +        while (keys.hasNext()) {
  +            this.componentHandlers.remove(keys.next());
  +        }
  +
  +        keyList.clear();
       }
  +
  +    /**
  +     * Return an instance of a component based on a hint.  The Composer has already selected the
  +     * role, so the only part left it to make sure the Component is handled.
  +     */
  +    public Component select( Object hint )
  +    throws ComponentException {
  +
  +        if (disposed) throw new IllegalStateException("You cannot select a Component from a disposed ComponentSelector");
  +
  +        DefaultComponentHandler handler = null;
  +        Component component = null;
  +
  +        if ( hint == null ) {
  +            getLogger().error(this.getName() + ": ComponentSelector Attempted to retrieve component with null hint.");
  +            throw new ComponentException("Attempted to retrieve component with null hint.");
  +        }
   
  -    public void release( final Component component )
  -    {
  -        // if the ComponentManager handled pooling, it would be
  -        // returned to the pool here.
  +        handler = (DefaultComponentHandler) this.componentHandlers.get(hint);
  +        // Retrieve the instance of the requested component
  +        if ( handler == null ) {
  +            throw new ComponentException(this.getName() + ": ComponentSelector could not find the component for hint: " + hint);
  +        }
  +
  +        try {
  +            component = handler.get();
  +        } catch (Exception e) {
  +            throw new ComponentException(this.getName() + ": ComponentSelector could not access the Component for you", e);
  +        }
  +
  +        if (component == null) {
  +            throw new ComponentException(this.getName() + ": ComponentSelector could not find the component for hint: " + hint);
  +        }
  +
  +        this.componentMapping.put(component, handler);
  +        return component;
  +    }
  +
  +    /**
  +     * Default Configuration handler for ComponentSelector.
  +     */
  +    public void configure(Configuration conf) throws ConfigurationException {
  +        this.conf = conf;
  +        getLogger().debug("ComponentSelector setting up with root element: " + conf.getName());
  +
  +        Configuration[] hints = conf.getChildren("hint");
  +        HashMap hintMap = new HashMap();
  +
  +        for (int i = 0; i < hints.length; i++) {
  +            hintMap.put(hints[i].getAttribute("short-hand").trim(), hints[i].getAttribute("class").trim());
  +        }
  +
  +        this.hints = Collections.unmodifiableMap(hintMap);
  +
  +        Iterator shorthand = this.hints.keySet().iterator();
  +        Configuration[] instances = null;
  +
  +        while (shorthand.hasNext()) {
  +            String type = (String) shorthand.next();
  +            Class clazz = null;
  +
  +            try {
  +                clazz = this.getClass().getClassLoader().loadClass((String) this.hints.get(type));
  +            } catch (Exception e) {
  +                getLogger().error("ComponentSelector The component instance for \"" + type + "\" has an invalid class name.", e);
  +                throw new ConfigurationException("The component instance for '" + type + "' has an invalid class name.", e);
  +            }
  +
  +            instances = conf.getChildren(type);
  +
  +            for (int i = 0; i < instances.length; i++) {
  +                Object hint = instances[i].getAttribute("name").trim();
  +
  +                try {
  +                    this.addComponent(hint, clazz, instances[i]);
  +                } catch (Exception e) {
  +                    getLogger().error("ComponentSelector The component instance for \"" + hint + "\" has an invalid class name.", e);
  +                    throw new ConfigurationException("The component instance for '" + hint + "' has an invalid class name.", e);
  +                }
  +            }
  +        }
  +
  +        instances = conf.getChildren("component-instance");
  +
  +        for (int i = 0; i < instances.length; i++) {
  +            Object hint = instances[i].getAttribute("name").trim();
  +            String className = (String) instances[i].getAttribute("class").trim();
  +
  +            try {
  +                this.addComponent(hint, this.getClass().getClassLoader().loadClass(className), instances[i]);
  +            } catch (Exception e) {
  +                getLogger().error("ComponentSelector The component instance for \"" + hint + "\" has an invalid class name.", e);
  +                throw new ConfigurationException("The component instance for '" + hint + "' has an invalid class name.", e);
  +            }
  +        }
       }
   
       /**
  -     * Populate the ComponentSelector.
  +     * Release the Component to the propper ComponentHandler.
        */
  -    public void put(final Object hint, final Component component) {
  -        this.components.put(hint, component);
  +    public void release(Component component) {
  +        if (component == null) return;
  +        DefaultComponentHandler handler = (DefaultComponentHandler) this.componentMapping.get(component);
  +        if (handler == null) return;
  +        handler.put(component);
  +        this.componentMapping.remove(component);
  +    }
  +
  +    /** Add a new component to the manager.
  +     * @param hint the hint name for the new component.
  +     * @param component the class of this component.
  +     * @param Configuration the configuration for this component.
  +     */
  +    public void addComponent(Object hint, Class component, Configuration config)
  +    throws ComponentException {
  +        try {
  +            DefaultComponentHandler handler = new DefaultComponentHandler(component, config, this.manager, this.context);
  +            handler.setLogger(getLogger());
  +            handler.init();
  +            this.componentHandlers.put(hint, handler);
  +            getLogger().debug("Adding " + component.getName() + " for " + hint.toString());
  +        } catch (Exception e) {
  +            getLogger().error("Could not set up Component for hint: " + hint, e);
  +            throw new ComponentException ("Could not set up Component for hint: " + hint, e);
  +        }
       }
  +
  +    /** Add a static instance of a component to the manager.
  +     * @param hint the hint name for the component.
  +     * @param instance the instance of the component.
  +     */
  +    public void addComponentInstance(String hint, Object instance) {
  +        try {
  +            DefaultComponentHandler handler = new DefaultComponentHandler((Component) instance);
  +            handler.setLogger(getLogger());
  +            handler.init();
  +            this.componentHandlers.put(hint, handler);
  +            getLogger().debug("Adding " + instance.getClass().getName() + " for " + hint.toString());
  +        } catch (Exception e) {
  +            getLogger().error("Could not set up Component for hint: " + hint, e);
  +        }
  +    }
  +
  +    private static final String DEFAULT_NAME = "UnnamedSelector";
  +
  +    /**
  +     * Return this selector's configuration name or a default name if no such
  +     * configuration was provided. This accounts for the case when a static
  +     * component instance has been added through
  +     * <code>addComponentInstance</code> with no associated configuration
  +     */
  +   private String getName() {
  +     if (this.conf != null) {
  +       return this.conf.getName();
  +     }
  +
  +     return DEFAULT_NAME;
  +   }
   }
  
  
  
  1.3       +49 -35    jakarta-avalon/proposal/4.0/src/java/org/apache/framework/configuration/AbstractConfiguration.java
  
  Index: AbstractConfiguration.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/proposal/4.0/src/java/org/apache/framework/configuration/AbstractConfiguration.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- AbstractConfiguration.java	2001/04/04 15:29:50	1.2
  +++ AbstractConfiguration.java	2001/04/05 19:38:43	1.3
  @@ -17,13 +17,11 @@
    * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
    * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
    * @author <a href="mailto:fumagalli@exoffice.com">Pierpaolo Fumagalli</a>
  - * @version CVS $Revision: 1.2 $ $Date: 2001/04/04 15:29:50 $
  + * @version CVS $Revision: 1.3 $ $Date: 2001/04/05 19:38:43 $
    */
   public abstract class AbstractConfiguration
       implements Configuration
   {
  -    private static int PREFIX = 2;
  -
       /**
        * Returns the value of the configuration element as an <code>int</code>.
        */
  @@ -33,17 +31,17 @@
           final String value = getValue();
           try
           {
  -            if( value.startsWith("0x") )
  +            if( value.startsWith( "0x" ) )
               {
  -                return Integer.parseInt( value.substring(AbstractConfiguration.PREFIX), 16 );
  +                return Integer.parseInt( value.substring( 2 ), 16 );
               }
  -            else if( value.startsWith("0o") )
  +            else if( value.startsWith( "0o" ) )
               {
  -                return Integer.parseInt( value.substring(AbstractConfiguration.PREFIX), 8 );
  +                return Integer.parseInt( value.substring( 2 ), 8 );
               }
  -            else if( value.startsWith("0b") )
  +            else if( value.startsWith( "0b" ) )
               {
  -                return Integer.parseInt( value.substring(AbstractConfiguration.PREFIX), 2 );
  +                return Integer.parseInt( value.substring( 2 ), 2 );
               }
               else
               {
  @@ -82,17 +80,17 @@
           final String value = getValue();
           try
           {
  -            if( value.startsWith("0x") )
  +            if( value.startsWith( "0x" ) )
               {
  -                return Long.parseLong( value.substring(2), 16 );
  +                return Long.parseLong( value.substring( 2 ), 16 );
               }
  -            else if( value.startsWith("0o") )
  +            else if( value.startsWith( "0o" ) )
               {
  -                return Long.parseLong( value.substring(2), 8);
  +                return Long.parseLong( value.substring( 2 ), 8 );
               }
  -            else if( value.startsWith("0b") )
  +            else if( value.startsWith( "0b" ) )
               {
  -                return Long.parseLong(value.substring(2),2);
  +                return Long.parseLong( value.substring( 2 ), 2 );
               }
               else return Integer.parseInt(value);
           }
  @@ -160,8 +158,8 @@
           throws ConfigurationException
       {
           final String value = getValue();
  -        if( value.equals("true") ) return true;
  -        else if( value.equals("false") ) return false;
  +        if( value.equals( "true" ) ) return true;
  +        else if( value.equals( "false" ) ) return false;
           else
           {
               throw new ConfigurationException( "Cannot parse the value of the " +
  @@ -210,17 +208,17 @@
           final String value = getAttribute( name );
           try
           {
  -            if( value.startsWith("0x") )
  +            if( value.startsWith( "0x" ) )
               {
  -                return Integer.parseInt( value.substring(2), 16 );
  +                return Integer.parseInt( value.substring( 2 ), 16 );
               }
  -            else if( value.startsWith("0o") )
  +            else if( value.startsWith( "0o" ) )
               {
  -                return Integer.parseInt( value.substring(2), 8);
  +                return Integer.parseInt( value.substring( 2 ), 8);
               }
  -            else if( value.startsWith("0b") )
  +            else if( value.startsWith( "0b" ) )
               {
  -                return Integer.parseInt(value.substring(2),2);
  +                return Integer.parseInt( value.substring( 2 ), 2 );
               }
               else
               {
  @@ -262,17 +260,17 @@
   
           try
           {
  -            if( value.startsWith("0x") )
  +            if( value.startsWith( "0x" ) )
               {
  -                return Long.parseLong( value.substring(2), 16 );
  +                return Long.parseLong( value.substring( 2 ), 16 );
               }
  -            else if( value.startsWith("0o") )
  +            else if( value.startsWith( "0o" ) )
               {
  -                return Long.parseLong( value.substring(2), 8 );
  +                return Long.parseLong( value.substring( 2 ), 8 );
               }
  -            else if( value.startsWith("0b") )
  +            else if( value.startsWith( "0b" ) )
               {
  -                return Long.parseLong( value.substring(2), 2);
  +                return Long.parseLong( value.substring( 2 ), 2);
               }
               else
               {
  @@ -348,8 +346,8 @@
       {
           final String value = getAttribute( name );
   
  -        if( value.equals("true") ) return true;
  -        else if( value.equals("false") ) return false;
  +        if( value.equals( "true" ) ) return true;
  +        else if( value.equals( "false" ) ) return false;
           else
           {
               throw new ConfigurationException( "Cannot parse the value of the attribute \"" +
  @@ -396,14 +394,30 @@
        */
       public Configuration getChild( final String name )
       {
  -        final Iterator iterator = getChildren( name );
  -        if( iterator.hasNext() )
  +        return getChild( name, true );
  +    }
  +
  +    /**
  +     * Return the first <code>Configuration</code> object child of this
  +     * associated with the given name.
  +     */
  +    public Configuration getChild( final String name, final boolean createNew )
  +    {
  +        final Configuration[] children = getChildren( name );
  +        if( children.length > 0 )
           {
  -            return (Configuration)iterator.next();
  +            return children[ 0 ];
           }
           else
           {
  -            return new DefaultConfiguration( name, "-" );
  +            if( createNew )
  +            {
  +                return new DefaultConfiguration( name, "-" );
  +            }
  +            else
  +            {
  +                return null;
  +            }
           }
       }
   }
  
  
  
  1.2       +1 -1      jakarta-avalon/proposal/4.0/src/java/org/apache/framework/configuration/Configurable.java
  
  Index: Configurable.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/proposal/4.0/src/java/org/apache/framework/configuration/Configurable.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- Configurable.java	2001/03/15 04:35:02	1.1
  +++ Configurable.java	2001/04/05 19:38:43	1.2
  @@ -32,6 +32,6 @@
        *
        * @param configuration the class configurations.
        */
  -    void configure( Configuration configuration ) 
  +    void configure( Configuration configuration )
           throws ConfigurationException;
   }
  
  
  
  1.2       +16 -6     jakarta-avalon/proposal/4.0/src/java/org/apache/framework/configuration/Configuration.java
  
  Index: Configuration.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/proposal/4.0/src/java/org/apache/framework/configuration/Configuration.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- Configuration.java	2001/03/15 04:35:02	1.1
  +++ Configuration.java	2001/04/05 19:38:43	1.2
  @@ -7,8 +7,6 @@
    */
   package org.apache.framework.configuration;
   
  -import java.util.Iterator;
  -
   /**
    * <code>Configuration</code> is a interface encapsulating a configuration node
    * used to retrieve configuration values. This is a "read only" interface
  @@ -68,10 +66,18 @@
        * @param child The name of the child node.
        * @return Configuration
        */
  -//    Configuration getChild( String child, boolean createNew );
  +    Configuration getChild( String child, boolean createNew );
   
       /**
        * Return an <code>Iterator</code> of <code>Configuration<code>
  +     * elements containing all node children.
  +     *
  +     * @return The child nodes with name
  +     */
  +    Configuration[] getChildren();
  +
  +    /**
  +     * Return an <code>Iterator</code> of <code>Configuration<code>
        * elements containing all node children with the specified name.
        *
        * @pre name != null
  @@ -80,10 +86,14 @@
        * @param name The name of the children to get.
        * @return The child nodes with name
        */
  -    Iterator getChildren( String name );
  +    Configuration[] getChildren( String name );
   
  -    Configuration[] getChildrenAsArray(String name);
       /**
  +     * Return an array of all attribute names.
  +     */
  +    String[] getAttributeNames();
  +
  +    /**
        * Return the value of specified attribute.
        *
        * @pre paramName != null
  @@ -330,7 +340,7 @@
        * @pre name != null
        * @pre defaultValue != null
        * @post getAttributeAsFloat(name, defaultValue) != null
  -     * 
  +     *
        * @param name The name of the attribute you ask the value of.
        * @param defaultValue The default value desired.
        * @return float value of attribute. It will return the default
  
  
  
  1.3       +3 -3      jakarta-avalon/proposal/4.0/src/java/org/apache/framework/configuration/ConfigurationException.java
  
  Index: ConfigurationException.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/proposal/4.0/src/java/org/apache/framework/configuration/ConfigurationException.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ConfigurationException.java	2001/04/03 23:18:02	1.2
  +++ ConfigurationException.java	2001/04/05 19:38:43	1.3
  @@ -17,7 +17,7 @@
    * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
    * @author <a href="mailto:fumagalli@exoffice.com">Pierpaolo Fumagalli</a>
    */
  -public final class ConfigurationException 
  +public final class ConfigurationException
       extends CascadingException
   {
       /**
  @@ -25,7 +25,7 @@
        *
        * @param message The detail message for this exception.
        */
  -    public ConfigurationException( final String message ) 
  +    public ConfigurationException( final String message )
       {
           this( message, null );
       }
  @@ -36,7 +36,7 @@
        * @param message The detail message for this exception.
        * @param throwable the root cause of the exception
        */
  -    public ConfigurationException( final String message, final Throwable throwable ) 
  +    public ConfigurationException( final String message, final Throwable throwable )
       {
           super( message, throwable );
       }
  
  
  
  1.3       +55 -39    jakarta-avalon/proposal/4.0/src/java/org/apache/framework/configuration/DefaultConfiguration.java
  
  Index: DefaultConfiguration.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/proposal/4.0/src/java/org/apache/framework/configuration/DefaultConfiguration.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- DefaultConfiguration.java	2001/04/04 15:29:50	1.2
  +++ DefaultConfiguration.java	2001/04/05 19:38:43	1.3
  @@ -22,7 +22,7 @@
   public class DefaultConfiguration
       extends AbstractConfiguration
   {
  -    protected final static Iterator          EMPTY_ITERATOR = (new ArrayList(1)).iterator();
  +    protected final static Configuration[]   EMPTY_ARRAY = new Configuration[ 0 ];
   
       protected final String                   m_name;
       protected final String                   m_location;
  @@ -71,6 +71,27 @@
       }
   
       /**
  +     * Return an array of all attribute names.
  +     */
  +    public String[] getAttributeNames()
  +    {
  +        if( null == m_attributes ) return new String[ 0 ];
  +        else return (String[])m_attributes.keySet().toArray( new String[ 0 ] );
  +    }
  +
  +    /**
  +     * Return an <code>Iterator</code> of <code>Configuration<code>
  +     * elements containing all node children.
  +     *
  +     * @return The child nodes with name
  +     */
  +    public Configuration[] getChildren()
  +    {
  +        if( null == m_children ) return new Configuration[ 0 ];
  +        else return (Configuration[])m_children.toArray( new Configuration[ 0 ] );
  +    }
  +
  +    /**
        * Returns the value of the attribute specified by its name as a
        * <code>String</code>.
        *
  @@ -93,18 +114,12 @@
   
       /**
        * Return the first <code>Configuration</code> object child of this
  -     * associated with the given name. If none exists a new one of that name is created.
  -     *
  -     * @param name The name of the required child <code>Configuration</code>.
  +     * associated with the given name.
        */
  -    public Configuration getChild( final String name )
  +    public Configuration getChild( final String name, final boolean createNew )
       {
  -        if( null == m_children )
  +        if( null != m_children )
           {
  -            return new DefaultConfiguration( name, "-" );
  -        }
  -        else
  -        {
               final int size = m_children.size();
               for( int i = 0; i < size; i++ )
               {
  @@ -114,9 +129,16 @@
                       return configuration;
                   }
               }
  +        }
   
  +        if( createNew )
  +        {
               return new DefaultConfiguration( name, "-" );
           }
  +        else
  +        {
  +            return null;
  +        }
       }
   
       /**
  @@ -127,9 +149,9 @@
        *
        * @param name The name of the required children <code>Configuration</code>.
        */
  -    public Iterator getChildren( final String name )
  +    public Configuration[] getChildren( final String name )
       {
  -        if( null == m_children ) return EMPTY_ITERATOR;
  +        if( null == m_children ) return new Configuration[ 0 ];
           else
           {
               final ArrayList children = new ArrayList();
  @@ -143,37 +165,11 @@
                       children.add( configuration );
                   }
               }
  -
  -            return children.iterator();
  -        }
  -    }
  -
  -    public Configuration[] getChildrenAsArray( final String name )
  -    {
  -        if( null == m_children ) return new Configuration[0];
  -        else
  -        {
  -            final ArrayList children = new ArrayList();
  -            final int size = m_children.size();
   
  -            for( int i = 0; i < size; i++ )
  -            {
  -                final Configuration configuration = (Configuration)m_children.get( i );
  -                if( name.equals( configuration.getName() ) )
  -                {
  -                    children.add( configuration );
  -                }
  -            }
  -            Configuration[] response = new Configuration[children.size()];
  -            for (int i = 0; i < children.size(); i++) {
  -                response[i] = (Configuration) children.get(i);
  -            }
  -            return response;
  +            return (Configuration[])children.toArray( new Configuration[ 0 ] );
           }
       }
   
  -
  -
       /**
        * Append data to the value of this configuration element.
        */
  @@ -189,6 +185,17 @@
           }
       }
   
  +    public void setValue( final String value )
  +    {
  +        m_value = value;
  +    }
  +
  +    public void setAttribute( final String name, final String value )
  +    {
  +        if( null == m_attributes ) m_attributes = new HashMap();
  +        m_attributes.put( name, value );
  +    }
  +
       /**
        * Add an attribute to this configuration element, returning its old
        * value or <b>null</b>.
  @@ -211,6 +218,15 @@
           }
   
           m_children.add( configuration );
  +    }
  +
  +    /**
  +     * Remove a child <code>Configuration</code> to this configuration element.
  +     */
  +    public void removeChild( final Configuration configuration )
  +    {
  +        if( null == m_children ) return;
  +        m_children.remove( configuration );
       }
   
       /**
  
  
  
  1.2       +5 -5      jakarta-avalon/proposal/4.0/src/java/org/apache/framework/configuration/DefaultConfigurationBuilder.java
  
  Index: DefaultConfigurationBuilder.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/proposal/4.0/src/java/org/apache/framework/configuration/DefaultConfigurationBuilder.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- DefaultConfigurationBuilder.java	2001/04/03 23:18:02	1.1
  +++ DefaultConfigurationBuilder.java	2001/04/05 19:38:43	1.2
  @@ -28,9 +28,9 @@
   public class DefaultConfigurationBuilder
       implements ConfigurationBuilder
   {
  -    protected final static String                 DEFAULT_PARSER = 
  +    protected final static String                 DEFAULT_PARSER =
           "org.apache.xerces.parsers.SAXParser";
  -    protected final static String                 PARSER = 
  +    protected final static String                 PARSER =
           System.getProperty("org.xml.sax.parser", DEFAULT_PARSER );
   
       protected SAXConfigurationHandler             m_handler;
  @@ -45,7 +45,7 @@
       {
           //yaya the bugs with some compilers and final variables ..
           m_handler = getHandler();
  -        try 
  +        try
           {
               m_parser = XMLReaderFactory.createXMLReader( parserClass );
               //m_parser.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
  @@ -67,12 +67,12 @@
           throws SAXException, IOException, ConfigurationException
       {
           final InputStream input = new FileInputStream( resource );
  -      
  +
           try { return build( input ); }
           finally
           {
               try { input.close(); }
  -            catch( final IOException ioe ) {}            
  +            catch( final IOException ioe ) {}
           }
       }
   
  
  
  
  1.2       +8 -15     jakarta-avalon/proposal/4.0/src/java/org/apache/framework/configuration/Parameters.java
  
  Index: Parameters.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/proposal/4.0/src/java/org/apache/framework/configuration/Parameters.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- Parameters.java	2001/03/15 04:35:02	1.1
  +++ Parameters.java	2001/04/05 19:38:43	1.2
  @@ -16,7 +16,7 @@
    *
    * @author <a href="mailto:fumagalli@exoffice.com">Pierpaolo Fumagalli</a>
    */
  -public final class Parameters
  +public class Parameters
   {
       protected HashMap            m_parameters;
   
  @@ -259,33 +259,26 @@
        * Create a <code>Parameters</code> object from a <code>Configuration</code>
        * object.
        */
  -    public static Parameters fromConfiguration( final Configuration configuration  )
  +    public static Parameters fromConfiguration( final Configuration configuration )
           throws ConfigurationException
       {
           if( null == configuration )
           {
               throw new ConfigurationException( "You cannot convert to parameters with " +
  -                                              "a null Configuration");
  +                                              "a null Configuration" );
           }
   
  -        final Iterator parameters = configuration.getChildren("parameter");
  +        final Configuration[] parameters = configuration.getChildren( "parameter" );
           final Parameters param = new Parameters();
   
  -        while( parameters.hasNext() )
  +        for (int i = 0; i <  parameters.length; i++ )
           {
               try
               {
  -                final Configuration child = (Configuration)parameters.next();
  -                final String name = child.getAttribute( "name" );
  -                final String value = child.getAttribute( "value" );
  +                final String name = parameters[ i ].getAttribute( "name" );
  +                final String value = parameters[ i ].getAttribute( "value" );
                   param.setParameter( name, value );
  -            } 
  -            catch( final ClassCastException cce )
  -            {
  -                // ignore this.  Temporary work around until the Iterator
  -                // is guaranteed to return Configuration values.  Unfortunately
  -                // there are problems with empty strings getting in there.
  -            } 
  +            }
               catch( final Exception e )
               {
                   throw new ConfigurationException( "Cannot process Configurable", e );
  
  
  
  1.2       +1 -1      jakarta-avalon/proposal/4.0/src/java/org/apache/framework/configuration/Reconfigurable.java
  
  Index: Reconfigurable.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/proposal/4.0/src/java/org/apache/framework/configuration/Reconfigurable.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- Reconfigurable.java	2001/03/15 04:35:02	1.1
  +++ Reconfigurable.java	2001/04/05 19:38:43	1.2
  @@ -15,7 +15,7 @@
    * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
    * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
    */
  -public interface Reconfigurable 
  +public interface Reconfigurable
       extends Configurable
   {
       void reconfigure( Configuration configuration ) throws ConfigurationException;
  
  
  
  1.2       +43 -34    jakarta-avalon/proposal/4.0/src/java/org/apache/framework/configuration/SAXConfigurationHandler.java
  
  Index: SAXConfigurationHandler.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/proposal/4.0/src/java/org/apache/framework/configuration/SAXConfigurationHandler.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- SAXConfigurationHandler.java	2001/04/03 23:18:02	1.1
  +++ SAXConfigurationHandler.java	2001/04/05 19:38:43	1.2
  @@ -22,13 +22,14 @@
    * @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
    * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
    */
  -public class SAXConfigurationHandler 
  -    extends DefaultHandler 
  +public class SAXConfigurationHandler
  +    extends DefaultHandler
       implements ErrorHandler
   {
       protected final ArrayList              m_elements        = new ArrayList();
       protected Configuration                m_configuration;
       protected Locator                      m_locator;
  +    protected String                       m_value;
   
       public Configuration getConfiguration()
       {
  @@ -47,57 +48,65 @@
       }
   
       public void characters( final char[] ch, int start, int end )
  -        throws SAXException 
  +        throws SAXException
       {
           final String value = (new String( ch, start, end )).trim();
   
           if( value.equals( "" ) ) return;
  -        
  -        final DefaultConfiguration configuration = 
  -            (DefaultConfiguration)m_elements.get( m_elements.size() - 1 );
   
  -        if( 0 != configuration.getChildCount() )
  -        {
  -            throw new SAXException( "Not allowed to define mixed content in the " +
  -                                    "element " + configuration.getName() + " at " +
  -                                    configuration.getLocation() );
  -        }
  -
  -        configuration.appendValueData( value );
  +        if( null == m_value ) m_value = value;
  +        else m_value += value;
       }
   
  -    public void endElement( final String namespaceURI, 
  +    public void endElement( final String namespaceURI,
                               final String localName,
  -                            final String rawName ) 
  +                            final String rawName )
  +        throws SAXException
       {
  +        if( null != m_value )
  +        {
  +            final DefaultConfiguration configuration =
  +                (DefaultConfiguration)m_elements.get( m_elements.size() - 1 );
  +
  +            if( 0 != configuration.getChildCount() )
  +            {
  +                throw new SAXException( "Not allowed to define mixed content in the " +
  +                                        "element " + configuration.getName() + " at " +
  +                                        configuration.getLocation() );
  +            }
  +
  +            configuration.setValue( m_value );
  +            m_value = null;
  +        }
  +
           final int location = m_elements.size() - 1;
           final Object object = m_elements.remove( location );
  -        
  +
           if( 0 == location )
           {
               m_configuration = (Configuration)object;
           }
       }
   
  -    protected DefaultConfiguration createConfiguration( final String localName, 
  +    protected DefaultConfiguration createConfiguration( final String localName,
                                                           final String location )
       {
           return new DefaultConfiguration( localName, location );
       }
   
  -    public void startElement( final String namespaceURI, 
  +    public void startElement( final String namespaceURI,
                                 final String localName,
  -                              final String rawName, 
  -                              final Attributes attributes ) 
  -        throws SAXException 
  +                              final String rawName,
  +                              final Attributes attributes )
  +        throws SAXException
       {
  -        final DefaultConfiguration configuration = 
  +        final DefaultConfiguration configuration =
               createConfiguration( localName, getLocationString() );
           final int size = m_elements.size() - 1;
   
           if( size > -1 )
           {
  -            final DefaultConfiguration parent = 
  +            final DefaultConfiguration parent =
                   (DefaultConfiguration)m_elements.get( size );
   
               if( null != parent.getValue( null ) )
  @@ -109,16 +118,16 @@
   
               parent.addChild( configuration );
           }
  -        
  +
           m_elements.add( configuration );
  -        
  +
           final int attributesSize = attributes.getLength();
  -        
  -        for( int i = 0; i < attributesSize; i++ ) 
  +
  +        for( int i = 0; i < attributesSize; i++ )
           {
               final String name = attributes.getQName( i );
               final String value = attributes.getValue( i );
  -            configuration.addAttribute( name, value );
  +            configuration.setAttribute( name, value );
           }
       }
   
  @@ -126,7 +135,7 @@
        * This just throws an exception on a parse error.
        */
       public void error( final SAXParseException exception )
  -        throws SAXException 
  +        throws SAXException
       {
           throw exception;
       }
  @@ -143,8 +152,8 @@
       /**
        * This just throws an exception on a parse error.
        */
  -    public void fatalError( final SAXParseException exception ) 
  -        throws SAXException 
  +    public void fatalError( final SAXParseException exception )
  +        throws SAXException
       {
           throw exception;
       }
  @@ -154,8 +163,8 @@
           if( null == m_locator ) return "Unknown";
           else
           {
  -            return 
  -                m_locator.getSystemId() + ":" + 
  +            return
  +                m_locator.getSystemId() + ":" +
                   m_locator.getLineNumber() + ":" +
                   m_locator.getColumnNumber();
           }
  
  
  
  1.3       +0 -3      jakarta-avalon/src/java/org/apache/avalon/camelot/pipeline/StartupPipeline.java
  
  Index: StartupPipeline.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/src/java/org/apache/avalon/camelot/pipeline/StartupPipeline.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- StartupPipeline.java	2001/02/28 08:12:49	1.2
  +++ StartupPipeline.java	2001/04/05 19:38:44	1.3
  @@ -24,9 +24,6 @@
           addStage( AvalonState.COMPOSED, new CompositionStage() );
           addStage( AvalonState.CONFIGURED, new ConfigurationStage() );
   
  -        //will be removed in future...
  -        addStage( AvalonState.CONFIGURED, new OldConfigurationStage() );
  -
           addStage( AvalonState.INITIALIZED, new InitializationStage() );
           addStage( AvalonState.STARTED, new StartStage() );
           addStage( AvalonState.RUNNING, new RunnerStage() );
  
  
  
  1.6       +3 -3      jakarta-avalon/src/java/org/apache/avalon/util/pool/AbstractPool.java
  
  Index: AbstractPool.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon/src/java/org/apache/avalon/util/pool/AbstractPool.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- AbstractPool.java	2001/04/02 00:13:56	1.5
  +++ AbstractPool.java	2001/04/05 19:38:44	1.6
  @@ -21,8 +21,8 @@
    *
    * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
    */
  -public class AbstractPool 
  -    extends AbstractLoggable 
  +public class AbstractPool
  +    extends AbstractLoggable
       implements Pool, ThreadSafe
   {
       protected final ObjectFactory  m_factory;
  @@ -83,7 +83,7 @@
           }
       }
   
  -    protected void init() 
  +    protected void init()
           throws Exception
       {
           for( int i = 0; i < m_min; i++ )
  
  
  

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