You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@avalon.apache.org by do...@apache.org on 2001/04/18 15:16:37 UTC

cvs commit: jakarta-avalon/src/java/org/apache/excalibur/component DefaultComponentFactory.java DefaultComponentHandler.java DefaultComponentManager.java DefaultComponentPool.java DefaultComponentPoolController.java DefaultComponentSelector.java DefaultRoleManager.java RoleManager.java

donaldp     01/04/18 06:16:37

  Added:       src/java/org/apache/excalibur/component
                        DefaultComponentFactory.java
                        DefaultComponentHandler.java
                        DefaultComponentManager.java
                        DefaultComponentPool.java
                        DefaultComponentPoolController.java
                        DefaultComponentSelector.java
                        DefaultRoleManager.java RoleManager.java
  Log:
  Add in coocoon CM implementation. Look how to generalize this and move parts back into avalon.
  
  Revision  Changes    Path
  1.1                  jakarta-avalon/src/java/org/apache/excalibur/component/DefaultComponentFactory.java
  
  Index: DefaultComponentFactory.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 file.
   */
  package org.apache.excalibur.component;
  
  import org.apache.avalon.Disposable;
  import org.apache.avalon.Initializable;
  import org.apache.avalon.Startable;
  import org.apache.avalon.Stoppable;
  import org.apache.avalon.component.ComponentManager;
  import org.apache.avalon.component.Composable;
  import org.apache.avalon.configuration.Configurable;
  import org.apache.avalon.configuration.Configuration;
  import org.apache.avalon.context.Context;
  import org.apache.avalon.context.Contextualizable;
  import org.apache.avalon.logger.AbstractLoggable;
  import org.apache.avalon.logger.Loggable;
  import org.apache.avalon.thread.ThreadSafe;
  import org.apache.excalibur.pool.ObjectFactory;
  import org.apache.excalibur.pool.Pool;
  import org.apache.excalibur.pool.Poolable;
  
  /**
   * Factory for Avalon 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.1 $ $Date: 2001/04/18 13:16:36 $
   */
  public class DefaultComponentFactory
      extends AbstractLoggable
      implements ObjectFactory, ThreadSafe
  {
      /** The class which this <code>ComponentFactory</code>
       * should create.
       */
      private Class                   m_componentClass;
  
      /** The Context for the component
       */
      private Context                 m_context;
  
      /** The component manager for this component.
       */
      private ComponentManager        m_componentManager;
  
      /** The configuration for this component.
       */
      private Configuration           m_configuration;
  
      /** The RoleManager for child ComponentSelectors
       */
      private RoleManager             m_roles;
  
      /** Construct a new component factory for the specified component.
       * @param componentClass the class to instantiate (must have a default constructor).
       * @param configuration the <code>Configuration</code> object to pass to new instances.
       * @param componentManager the component manager to pass to <code>Composable</code>s.
       */
      public DefaultComponentFactory( final Class componentClass,
                                      final Configuration configuration,
                                      final ComponentManager componentManager,
                                      final Context context,
                                      final RoleManager roles )
      {
          m_componentClass = componentClass;
          m_configuration = configuration;
          m_componentManager = componentManager;
          m_context = context;
          m_roles = roles;
      }
  
      public Object newInstance()
          throws Exception
      {
          final Object component = m_componentClass.newInstance();
  
          getLogger().debug( "ComponentFactory creating new instance of " +
                             m_componentClass.getName() + "." );
  
          if( component instanceof Loggable )
          {
              ((Loggable)component).setLogger( getLogger() );
          }
  
          if( component instanceof Contextualizable )
          {
              ((Contextualizable)component).contextualize( m_context );
          }
  
          if( component instanceof Composable )
          {
              ((Composable)component).compose( m_componentManager );
          }
  
          if ( component instanceof DefaultComponentSelector )
          {
              ((DefaultComponentSelector)component).setRoleManager( m_roles );
          }
  
          if( component instanceof Configurable )
          {
              ((Configurable)component).configure( m_configuration );
          }
  
          if( component instanceof Initializable )
          {
              ((Initializable)component).init();
          }
  
          if( component instanceof Startable )
          {
              ((Startable)component).start();
          }
  
          return component;
      }
  
      public final Class getCreatedClass()
      {
          return m_componentClass;
      }
  
      public final void decommission( final Object component )
          throws Exception
      {
          getLogger().debug( "ComponentFactory decommissioning instance of " +
                             m_componentClass.getName() + "." );
  
          if( component instanceof Stoppable )
          {
              ((Stoppable)component).stop();
          }
  
          if( component instanceof Disposable )
          {
              ((Disposable)component).dispose();
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/java/org/apache/excalibur/component/DefaultComponentHandler.java
  
  Index: DefaultComponentHandler.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 file.
   */
  package org.apache.excalibur.component;
  
  import org.apache.avalon.Disposable;
  import org.apache.avalon.Initializable;
  import org.apache.avalon.Stoppable;
  import org.apache.avalon.component.Component;
  import org.apache.avalon.component.ComponentManager;
  import org.apache.avalon.configuration.Configuration;
  import org.apache.avalon.context.Context;
  import org.apache.avalon.logger.AbstractLoggable;
  import org.apache.avalon.thread.ThreadSafe;
  import org.apache.excalibur.pool.Poolable;
  import org.apache.log.Logger;
  
  /**
   * The DefaultComponentHandler to make sure components are initialized
   * and destroyed correctly.
   *
   * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
   * @version CVS $Revision: 1.1 $ $Date: 2001/04/18 13:16:36 $
   */
  class DefaultComponentHandler
      extends AbstractLoggable
      implements Initializable, Disposable
  {
      /** Indicates that the Handler is holding a <code>ThreadSafe</code> Component */
      private final static int           THREADSAFE      = 0;
  
      /** Indicates that the Handler is holding a <code>Poolable</code> Component */
      private final static int           POOLABLE        = 1;
  
      /** Indicates that the Handler is holding a <code>SingleThreaded</code> Component */
      private final static int           SINGLETHREADED  = 2;
  
      /** The instance of the ComponentFactory that creates and disposes of the Component */
      private DefaultComponentFactory    m_factory;
  
      /** The pool of components for <code>Poolable</code> Components */
      private DefaultComponentPool       m_pool;
  
      /** The instance of the Component for <code>ThreadSafe</code> Components */
      private Component                  m_instance;
  
      /** The type of the Component: THREADSAFE, POOLABLE, or SINGLETHREADED */
      private final int                  m_type;
  
      /** State management boolean stating whether the Handler is initialized or not */
      private boolean                    m_initialized   = false;
  
      /** State management boolean stating whether the Handler is disposed or not */
      private boolean                    m_disposed      = false;
  
      /**
       * Create a ComponentHandler that takes care of hiding the details of
       * whether a Component is ThreadSafe, Poolable, or SingleThreaded.
       * It falls back to SingleThreaded if not specified.
       */
      DefaultComponentHandler( final Class componentClass,
                               final Configuration config,
                               final ComponentManager manager,
                               final Context context,
                               final RoleManager roles )
          throws Exception
      {
          m_factory = new DefaultComponentFactory( componentClass, config, manager, context, roles );
  
          if( Poolable.class.isAssignableFrom( componentClass ) )
          {
              m_pool = new DefaultComponentPool( m_factory );
              m_type = POOLABLE;
          }
          else if( ThreadSafe.class.isAssignableFrom( componentClass ) )
          {
              m_type = THREADSAFE;
          }
          else
          {
              m_type = SINGLETHREADED;
          }
      }
  
      /**
       * Create a ComponentHandler that takes care of hiding the details of
       * whether a Component is ThreadSafe, Poolable, or SingleThreaded.
       * It falls back to SingleThreaded if not specified.
       */
      DefaultComponentHandler( final Component component )
          throws Exception
      {
          m_type = THREADSAFE;
          m_instance = component;
      }
  
      /**
       * Sets the logger that the ComponentHandler will use.
       */
      public void setLogger( final Logger logger )
      {
          if( null != m_factory )
          {
              m_factory.setLogger( logger );
          }
  
          if( null != m_pool )
          {
              m_pool.setLogger( logger );
          }
  
          super.setLogger( logger );
      }
  
      /**
       * Initialize the ComponentHandler.
       */
      public void init()
      {
          if( m_initialized ) return;
  
          switch( m_type )
          {
          case THREADSAFE:
              try
              {
                  if( null == m_instance )
                  {
                      m_instance = (Component)m_factory.newInstance();
                  }
              }
              catch( final Exception e )
              {
                  getLogger().error( "Cannot use component: " +
                                     m_factory.getCreatedClass().getName(), e );
              }
              break;
  
          case POOLABLE:
              try
              {
                  m_pool.init();
              }
              catch( Exception e )
              {
                  getLogger().error( "Cannot use component: " + m_factory.getCreatedClass().getName(), e );
              }
              break;
  
          default:
              // Nothing to do for SingleThreaded Components
              break;
          }
  
          m_initialized = true;
      }
  
      /**
       * Get a reference of the desired Component
       */
      public Component get()
          throws Exception
      {
          if( ! m_initialized )
          {
              throw new IllegalStateException( "You cannot get a component from an uninitialized holder." );
          }
  
          if( m_disposed )
          {
              throw new IllegalStateException( "You cannot get a component from a disposed holder" );
          }
  
          Component component = null;
  
          switch( m_type )
          {
          case THREADSAFE:
              component = m_instance;
              break;
  
          case POOLABLE:
              component = (Component)m_pool.get();
              break;
  
          default:
              component = (Component)m_factory.newInstance();
              break;
          }
  
          return component;
      }
  
      /**
       * Return a reference of the desired Component
       */
      public void put( final Component component )
      {
          if( !m_initialized )
          {
              throw new IllegalStateException( "You cannot put a component in an uninitialized holder." );
          }
  
          if( m_disposed )
          {
              throw new IllegalStateException( "You cannot put a component in a disposed holder" );
          }
  
          switch( m_type )
          {
          case THREADSAFE:
              // Nothing to do for ThreadSafe Components
              break;
  
          case POOLABLE:
              m_pool.put( (Poolable)component );
              break;
  
          default:
              try
              {
                  m_factory.decommission( component );
              }
              catch( final Exception e )
              {
                  getLogger().warn( "Error decommissioning component: " +
                                    m_factory.getCreatedClass().getName(), e);
              }
              break;
          }
      }
  
      /**
       * Dispose of the ComponentHandler and any associated Pools and Factories.
       */
      public void dispose()
      {
          m_disposed = true;
  
          try
          {
              switch( m_type )
              {
              case THREADSAFE:
                  if( null != m_factory )
                  {
                      m_factory.decommission( m_instance );
                  }
                  else
                  {
                      if( m_instance instanceof Stoppable )
                      {
                          ((Stoppable)m_instance).stop();
                      }
  
                      if( m_instance instanceof Disposable )
                      {
                          ((Disposable)m_instance).dispose();
                      }
                  }
                  m_instance = null;
                  break;
  
              case POOLABLE:
                  if( m_pool instanceof Disposable )
                  {
                      ((Disposable)m_pool).dispose();
                  }
  
                  m_pool = null;
                  break;
  
              default:
                  // do nothing here
                  break;
              }
  
              if( m_factory instanceof Disposable )
              {
                  ((Disposable)m_factory).dispose();
              }
              m_factory = null;
          }
          catch( final Exception e )
          {
              getLogger().warn( "Error decommissioning component: " +
                                m_factory.getCreatedClass().getName(), e );
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/java/org/apache/excalibur/component/DefaultComponentManager.java
  
  Index: DefaultComponentManager.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 file.
   */
  package org.apache.excalibur.component;
  
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Map;
  import org.apache.avalon.Disposable;
  import org.apache.avalon.Initializable;
  import org.apache.avalon.component.Component;
  import org.apache.avalon.component.ComponentException;
  import org.apache.avalon.component.ComponentManager;
  import org.apache.avalon.component.Composable;
  import org.apache.avalon.configuration.Configurable;
  import org.apache.avalon.configuration.Configuration;
  import org.apache.avalon.configuration.ConfigurationException;
  import org.apache.avalon.configuration.DefaultConfiguration;
  import org.apache.avalon.context.Context;
  import org.apache.avalon.context.Contextualizable;
  import org.apache.avalon.logger.AbstractLoggable;
  
  /**
   * 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.1 $ $Date: 2001/04/18 13:16:36 $
   */
  public class DefaultComponentManager
      extends AbstractLoggable
      implements ComponentManager, Configurable, Contextualizable, Disposable
  {
      /** The application context for components
       */
      private Context      m_context;
  
      /** Static component mapping handlers.
       */
      private Map          m_componentMapping;
  
      /** Static component handlers.
       */
      private Map          m_componentHandlers;
  
      /** RoleInfos.
       */
      private RoleManager  m_roles;
  
      /** Is the Manager disposed or not? */
      private boolean      m_disposed;
  
      public DefaultComponentManager()
      {
          // Setup the maps.
          m_componentHandlers = Collections.synchronizedMap( new HashMap() );
          m_componentMapping = Collections.synchronizedMap( new HashMap() );
      }
  
      /** Set up the Component's Context.
       */
      public void contextualize( final Context context )
      {
          //HACK: Is this really needed ??? (Isn't a symtom of fault elsewhere in system)
          if( null == m_context )
          {
              m_context = context;
          }
      }
  
      /** Properly dispose of the Child handlers.
       */
      public synchronized void dispose( )
      {
          m_disposed = true;
  
          Iterator keys = m_componentHandlers.keySet().iterator();
          final List keyList = new ArrayList();
  
          while( keys.hasNext() )
          {
              final Object key = keys.next();
              final DefaultComponentHandler handler =
                  (DefaultComponentHandler)m_componentHandlers.get( key );
  
              handler.dispose();
              keyList.add( key );
          }
  
          keys = keyList.iterator();
  
          while( keys.hasNext() )
          {
              m_componentHandlers.remove( keys.next() );
          }
  
          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( final String role )
          throws ComponentException
      {
  
          if( m_disposed )
          {
              throw new IllegalStateException( "You cannot lookup components " +
                                               "on a disposed ComponentManager" );
          }
  
          if( null == role )
          {
              final String message =
                  "ComponentManager Attempted to retrieve component with null role.";
              getLogger().error( message );
              throw new ComponentException( message );
          }
  
          DefaultComponentHandler handler = (DefaultComponentHandler)m_componentHandlers.get( role );
  
          // Retrieve the instance of the requested component
          if( null == handler )
          {
              getLogger().debug( "Could not find ComponentHandler, " +
                                 "attempting to create one for role: " + role );
  
              try
              {
                  final String className = m_roles.getDefaultClassNameForRole( role );
                  final Class componentClass =
                      getClass().getClassLoader().loadClass( className );
  
                  final Configuration configuration = new DefaultConfiguration( "", "-" );
  
                  handler =
                      new DefaultComponentHandler( componentClass,
                                                   configuration,
                                                   this,
                                                   m_context,
                                                   m_roles );
  
                  handler.setLogger( getLogger() );
                  handler.init();
              }
              catch( final Exception e )
              {
                  final String message =
                      "ComponentManager Could not find component for role: " + role;
                  getLogger().error( message, e );
                  throw new ComponentException( message, e );
              }
  
              m_componentHandlers.put( role, handler );
          }
  
          Component component = null;
  
          try
          {
              component = handler.get();
  
              if( component instanceof DefaultComponentSelector )
              {
                  ((DefaultComponentSelector)component).setRoleManager( m_roles );
              }
          }
          catch( final IllegalStateException ise )
          {
              handler.init();
  
              try
              {
                  component = handler.get();
              }
              catch( final Exception e )
              {
                  final String message = "Could not access the Component for role: " + role;
                  throw new ComponentException( message, e );
              }
          }
          catch( final Exception e )
          {
              final String message = "Could not access the Component for role: " + role;
              throw new ComponentException( message, e );
          }
  
          m_componentMapping.put(component, handler);
          return component;
      }
  
      /**
       * Configure the ComponentManager.
       */
      public void configure( final Configuration configuration )
          throws ConfigurationException
      {
          if( null == m_roles )
          {
              DefaultRoleManager role_info = new DefaultRoleManager();
              role_info.setLogger( getLogger() );
              role_info.configure( configuration );
              m_roles = role_info;
          }
  
          // Set components
  
          final Configuration[] configurations = configuration.getChildren();
  
          for( int i = 0; i < configurations.length; i++ )
          {
              String type = configurations[i].getName(); // types are already trimmed
  
              if( !type.equals( "role" ) )
              {
                  String role = configurations[ i ].getAttribute( "role", "" );
                  String className = configurations[ i ].getAttribute( "class", "" );
  
                  if( role.equals( "" ) )
                  {
                      role = m_roles.getRoleForName( type );
                  }
  
                  if( null != role && !role.equals( "" ) )
                  {
                      if( className.equals( "" ) )
                      {
                          className = m_roles.getDefaultClassNameForRole( role );
                      }
  
                      try
                      {
                          getLogger().debug( "Adding component (" + role + " = " + className + ")" );
                          final Class clazz =
                              getClass().getClassLoader().loadClass( className );
                          addComponent( role, clazz, configurations[ i ] );
                      }
                      catch( final Exception e )
                      {
                          final String message =
                              "Could not get class " + className + " for role " + role +
                              " on configuration element " + configurations[ i ].getName();
  
                          getLogger().error( message, e );
                          throw new ConfigurationException( message, e );
                      }
                  }
              }
          }
      }
  
      /**
       * Configure the RoleManager
       */
      public void setRoleManager( final RoleManager roles )
      {
          //HACK: Is this really necessary???
          if( null == m_roles )
          {
              m_roles = roles;
          }
      }
  
      /**
       * 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( final Component component )
      {
          if( null == component ) return;
  
          final DefaultComponentHandler handler =
              (DefaultComponentHandler)m_componentMapping.get( component );
  
          if( null != handler )
          {
              handler.put( component );
              m_componentMapping.remove( component );
          }
      }
  
      /** 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( final String role,
                                final Class component,
                                final Configuration configuration )
          throws ComponentException
      {
          try
          {
              final DefaultComponentHandler handler =
                  new DefaultComponentHandler( component, configuration, this, m_context, m_roles );
  
              handler.setLogger( getLogger() );
              m_componentHandlers.put( role, handler );
          }
          catch( final Exception e )
          {
              throw new ComponentException( "Could not set up Component for role: " + role, e );
          }
      }
  
      /** 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( final String role, final Object instance )
      {
          try
          {
              DefaultComponentHandler handler = new DefaultComponentHandler( (Component)instance );
              handler.setLogger( getLogger() );
              m_componentHandlers.put( role, handler );
          }
          catch( final Exception e )
          {
              getLogger().warn( "Could not set up Component for role: " + role, e );
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/java/org/apache/excalibur/component/DefaultComponentPool.java
  
  Index: DefaultComponentPool.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 file.
   */
  package org.apache.excalibur.component;
  
  import java.util.ArrayList;
  import java.util.List;
  import org.apache.avalon.Disposable;
  import org.apache.avalon.Initializable;
  import org.apache.avalon.logger.AbstractLoggable;
  import org.apache.avalon.thread.ThreadSafe;
  import org.apache.excalibur.concurrent.Lock;
  import org.apache.excalibur.pool.ObjectFactory;
  import org.apache.excalibur.pool.Pool;
  import org.apache.excalibur.pool.Poolable;
  import org.apache.excalibur.pool.Recyclable;
  
  /**
   * This is a implementation of <code>Pool</code> for SitemapComponents
   * that is thread safe.
   *
   * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
   * @author <a href="mailto:Giacomo.Pati@pwr.ch">Giacomo Pati</a>
   */
  public class DefaultComponentPool
      extends AbstractLoggable
      implements Pool, Initializable, Disposable, Runnable, ThreadSafe
  {
      public final static int  DEFAULT_POOL_SIZE     = 8;
  
      /** The resources that are currently free */
      protected List           m_availableResources  = new ArrayList();
  
      /** Resources that have been allocated out of the pool */
      protected List           m_usedResources       = new ArrayList();
  
      private Lock             m_mutex               = new Lock();
  
      private boolean          m_initialized;
      private boolean          m_disposed;
      private Thread           m_initializationThread;
      protected ObjectFactory  m_factory;
      protected int            m_initial             = DEFAULT_POOL_SIZE/2;
      protected int            m_maximum             = DEFAULT_POOL_SIZE;
  
      public DefaultComponentPool( final ObjectFactory factory )
          throws Exception
      {
          init( factory, DEFAULT_POOL_SIZE/2, DEFAULT_POOL_SIZE );
      }
  
      public DefaultComponentPool( final ObjectFactory factory,
                                   final int initial )
          throws Exception
      {
          init( factory, initial, initial );
      }
  
      public DefaultComponentPool( final ObjectFactory factory,
                                   final int initial,
                                   final int maximum )
          throws Exception
      {
          init( factory, initial, maximum );
      }
  
      private void init( final ObjectFactory factory,
                         final int initial,
                         final int maximum )
          throws Exception
      {
          m_factory = factory;
          m_initial = initial;
          m_maximum = maximum;
      }
  
      public void init()
          throws Exception
      {
          m_initializationThread = new Thread( this );
          m_initializationThread.start();
      }
  
      public void run()
      {
          try
          {
              m_mutex.lock();
  
              for( int i = 0; i < m_initial; i++ )
              {
                  try
                  {
                      m_availableResources.add( m_factory.newInstance() );
                  }
                  catch( final Exception e )
                  {
                      getLogger().warn( "Could not create poolable resource", e );
                  }
              }
  
              if( m_availableResources.size() > 0 )
              {
                  m_initialized = true;
              }
          }
          catch( final Exception e )
          {
              getLogger().debug( "ComponentPool.run()", e );
          }
          finally
          {
              m_mutex.unlock();
          }
      }
  
      public void dispose()
      {
          try
          {
              m_mutex.lock();
              m_disposed = true;
  
              while( !m_availableResources.isEmpty() )
              {
                  m_availableResources.remove( 0 );
              }
          }
          catch( final Exception e )
          {
              getLogger().debug( "ComponentPool.dispose()", e );
          }
          finally
          {
              m_mutex.unlock();
          }
      }
  
      /**
       * Allocates a resource when the pool is empty. By default, this method
       * returns null, indicating that the requesting. This
       * allows a thread pool to expand when necessary, allowing for spikes in
       * activity.
       *
       * @return A new resource
       */
      protected Poolable getOverflowResource()
          throws Exception
      {
          final Poolable poolable = (Poolable)m_factory.newInstance();
          getLogger().debug( "Component Pool - creating Overflow Resource:" +
                             " Resource=" + poolable +
                             " Available=" + m_availableResources.size() +
                             " Used=" + m_usedResources.size() );
          return poolable;
      }
  
      /** Requests a resource from the pool.
       * No extra information is associated with the allocated resource.
       * @return The allocated resource
       */
      public Poolable get()
          throws Exception
      {
          if( !m_initialized )
          {
              if( null == m_initializationThread )
              {
                  throw new IllegalStateException( "You cannot get a resource before " +
                                                   "the pool is initialized" );
              }
              else
              {
                  m_initializationThread.join();
                  m_initializationThread = null;
              }
          }
  
          if( m_disposed )
          {
              throw new IllegalStateException("You cannot get a resource after the pool is disposed");
          }
  
          Poolable resource = null;
  
          try
          {
              m_mutex.lock();
              // See if there is a resource in the pool already
  
              if( m_availableResources.size() > 0 )
              {
                  resource = (Poolable)m_availableResources.remove( 0 );
  
                  m_usedResources.add( resource );
              }
              else
              {
                  resource = getOverflowResource();
  
                  if( null != resource )
                  {
                      m_usedResources.add( resource );
                  }
              }
          }
          catch( final Exception e )
          {
              getLogger().debug( "ComponentPool.get()", e );
          }
          finally
          {
              m_mutex.unlock();
          }
  
          if( null == resource )
          {
              throw new RuntimeException( "Could not get the component from the pool" );
          }
  
          return resource;
      }
  
      /** Releases a resource back to the pool of available resources
       * @param resource The resource to be returned to the pool
       */
      public void put( Poolable resource )
      {
          int pos = -1;
  
          try
          {
              m_mutex.lock();
  
              // Make sure the resource is in the used list
              pos = m_usedResources.indexOf( resource );
  
              if( resource instanceof Recyclable )
              {
                  ((Recyclable)resource).recycle();
              }
  
              // If the resource was in the used list, remove it from the used list and
              // add it back to the free list
              if( pos >= 0 )
              {
                  m_usedResources.remove( pos );
  
                  if( m_availableResources.size() < m_maximum )
                  {
                      // If the available resources are below the maximum add this back.
                      m_availableResources.add( resource );
                  }
                  else
                  {
                      // If the available are above the maximum destroy this resource.
                      try
                      {
                          m_factory.decommission( resource );
  
                          getLogger().debug( "Component Pool - decommissioning Overflow Resource:" +
                                             " Resource=" + resource +
                                             " Available=" + m_availableResources.size() +
                                             " Used=" + m_usedResources.size() );
                          resource = null;
                      }
                      catch( final Exception e )
                      {
                          throw new RuntimeException( "caught exception decommissioning " +
                                                      "resource: " + resource);
                      }
                  }
              }
          }
          catch( final Exception e )
          {
              getLogger().debug( "ComponentPool.put()", e );
          }
          finally
          {
              m_mutex.unlock();
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/java/org/apache/excalibur/component/DefaultComponentPoolController.java
  
  Index: DefaultComponentPoolController.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 file.
   */
  package org.apache.excalibur.component;
  
  import org.apache.avalon.component.Component;
  import org.apache.avalon.component.ComponentManager;
  import org.apache.avalon.component.Composable;
  import org.apache.avalon.configuration.Configurable;
  import org.apache.avalon.configuration.Configuration;
  import org.apache.avalon.thread.ThreadSafe;
  import org.apache.excalibur.pool.PoolController;
  
  /**
   * This class holds a sitemap component which is not specially marked as having
   * a spezial behaviour or treatment.
   *
   * @author <a href="mailto:Giacomo.Pati@pwr.ch">Giacomo Pati</a>
   * @version CVS $Revision: 1.1 $ $Date: 2001/04/18 13:16:36 $
   */
  public class DefaultComponentPoolController
      implements PoolController, ThreadSafe, Component
  {
      /** Initial increase/decrease amount */
      public final static int  DEFAULT_AMOUNT      = 8;
  
      /** Current increase/decrease amount */
      protected int            m_amount            = DEFAULT_AMOUNT;
  
      /** The last direction to increase/decrease >0 means increase, <0 decrease */
      protected int            m_sizing_direction  = 0;
  
      /**
       * Called when a Pool reaches it's minimum.
       * Return the number of elements to increase minimum and maximum by.
       * @return the element increase
       */
      public int grow()
      {
          /*
            if (m_sizing_direction < 0 && m_amount > 1)
            m_amount /= 2;
            m_sizing_direction = 1;
          */
          return m_amount;
      }
  
      /**
       * Called when a pool reaches it's maximum.
       * Returns the number of elements to decrease mi and max by.
       * @return the element decrease
       */
      public int shrink()
      {
          /*
            if (m_sizing_direction > 0 && m_amount > 1)
            m_amount /= 2;
            m_sizing_direction = -1;
          */
          return m_amount;
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/java/org/apache/excalibur/component/DefaultComponentSelector.java
  
  Index: DefaultComponentSelector.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 file.
   */
  package org.apache.excalibur.component;
  
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Map;
  import org.apache.avalon.Disposable;
  import org.apache.avalon.component.Component;
  import org.apache.avalon.component.ComponentException;
  import org.apache.avalon.component.ComponentManager;
  import org.apache.avalon.component.ComponentSelector;
  import org.apache.avalon.component.Composable;
  import org.apache.avalon.configuration.Configurable;
  import org.apache.avalon.configuration.Configuration;
  import org.apache.avalon.configuration.ConfigurationException;
  import org.apache.avalon.configuration.DefaultConfiguration;
  import org.apache.avalon.context.Context;
  import org.apache.avalon.context.Contextualizable;
  import org.apache.avalon.logger.AbstractLoggable;
  import org.apache.avalon.thread.ThreadSafe;
  
  /**
   * 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.1 $ $Date: 2001/04/18 13:16:36 $
   */
  public class DefaultComponentSelector
      extends AbstractLoggable
      implements Contextualizable, ComponentSelector, Composable, Configurable, ThreadSafe, Disposable
  {
      private static final String DEFAULT_NAME = "UnnamedSelector";
  
      /** The role name for this instance
       */
      private String           m_rolename;
  
      /** The application context for components
       */
      protected Context        m_context;
  
      /** The application context for components
       */
      private ComponentManager m_componentManager;
  
      /** Dynamic component handlers mapping.
       */
      private Map              m_componentMapping;
  
      /** Static configuraiton object.
       */
      private Configuration    m_configuration;
  
      /** Static component handlers.
       */
      private Map              m_componentHandlers;
  
      /** Flag for if this is disposed or not.
       */
      private boolean          m_disposed;
  
      /** Shorthand for hints
       */
      private Map              m_hints;
  
      /** The RoleManager to get hint shortcuts
       */
      private RoleManager      m_roles;
  
      /** Construct a new default component manager.
       */
      public DefaultComponentSelector()
      {
          // Setup the maps.
          m_componentHandlers = Collections.synchronizedMap( new HashMap() );
          m_componentMapping = Collections.synchronizedMap( new HashMap() );
      }
  
      /** Provide the application Context.
       */
      public void contextualize( final Context context )
      {
          if( null == m_context )
          {
              m_context = context;
          }
      }
  
      /** Compose the ComponentSelector so that we know what the parent ComponentManager is.
       */
      public void compose( final ComponentManager componentManager )
          throws ComponentException
      {
          //HACK: Is this necessary???
          if( null == m_componentManager )
          {
              m_componentManager = componentManager;
          }
      }
  
      /**
       * Properly dispose of all the ComponentHandlers.
       */
      public synchronized void dispose()
      {
          m_disposed = true;
  
          Iterator keys = m_componentHandlers.keySet().iterator();
          List keyList = new ArrayList();
  
          while( keys.hasNext() )
          {
              Object key = keys.next();
              DefaultComponentHandler handler =
                  (DefaultComponentHandler)m_componentHandlers.get( key );
  
              handler.dispose();
              keyList.add( key );
          }
  
          keys = keyList.iterator();
  
          while( keys.hasNext() )
          {
              m_componentHandlers.remove( keys.next() );
          }
  
          keyList.clear();
      }
  
      /**
       * Return an instance of a component based on a hint.  The Composable has already selected the
       * role, so the only part left it to make sure the Component is handled.
       */
      public Component select( final Object hint )
          throws ComponentException
      {
          if( m_disposed )
          {
              throw new IllegalStateException( "You cannot select a Component " +
                                               "from a disposed ComponentSelector" );
          }
  
          if( null == hint )
          {
              final String message =
                  getName() + ": ComponentSelector Attempted to retrieve component with null hint.";
              getLogger().error( message );
              throw new ComponentException( message );
          }
  
          DefaultComponentHandler handler = (DefaultComponentHandler)m_componentHandlers.get( hint );
  
          // Retrieve the instance of the requested component
          if( null == handler )
          {
              final String message =
                  getName() + ": ComponentSelector could not find the component for hint: " + hint;
              throw new ComponentException( message );
          }
  
          Component component = null;
  
          try
          {
              component = handler.get();
          }
          catch( final Exception e )
          {
              final String message =
                  getName() + ": ComponentSelector could not access the Component for hint: " + hint;
              throw new ComponentException( message, e );
          }
  
          if( null == component )
          {
              final String message =
                  getName() + ": ComponentSelector could not find the component for hint: " + hint;
              throw new ComponentException( message );
          }
  
          m_componentMapping.put( component, handler );
          return component;
      }
  
      /**
       * Default Configuration handler for ComponentSelector.
       */
      public void configure( final Configuration configuration )
          throws ConfigurationException
      {
          m_configuration = configuration;
          getLogger().debug( "ComponentSelector setting up with root element: " +
                             m_configuration.getName() );
  
          final String name = configuration.getName();
          if( name.equals( "component" ) )
          {
              m_rolename = m_configuration.getAttribute( "role" );
          }
          else
          {
              m_rolename = m_roles.getRoleForName( name );
          }
  
          Configuration[] instances = m_configuration.getChildren();
  
          for( int i = 0; i < instances.length; i++ )
          {
              final Object hint = instances[ i ].getAttribute( "name" ).trim();
              final String className;
  
              if("component-instance".equals(instances[i].getName())) {
                  className = (String)instances[i].getAttribute( "class" ).trim();
              } else {
                  className = m_roles.getDefaultClassNameForHint(m_rolename, instances[i].getName());
              }
  
              try
              {
                  final Class clazz = getClass().getClassLoader().loadClass( className );
                  addComponent( hint, clazz, instances[i]);
              }
              catch( final Exception e )
              {
                  final String message =
                      "The component instance for '" + hint + "' has an invalid class name.";
                  getLogger().error( message, e );
                  throw new ConfigurationException( message, e );
              }
          }
      }
  
      /**
       * Configure the RoleManager
       */
      public void setRoleManager( final RoleManager roles )
      {
          if( null == m_roles )
          {
              m_roles = roles;
          }
      }
  
      /**
       * Release the Component to the propper ComponentHandler.
       */
      public void release( final Component component )
      {
          if( null == component ) return;
  
          final DefaultComponentHandler handler =
              (DefaultComponentHandler)m_componentMapping.get( component );
  
          if( null == handler ) return;
  
          handler.put( component );
  
          m_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( final Object hint,
                                final Class component,
                                final Configuration configuration )
          throws ComponentException
      {
          try
          {
              final DefaultComponentHandler handler =
                  new DefaultComponentHandler( component,
                                               configuration,
                                               m_componentManager,
                                               m_context,
                                               m_roles );
  
              handler.setLogger( getLogger() );
              handler.init();
              m_componentHandlers.put( hint, handler );
              getLogger().debug( "Adding " + component.getName() + " for " + hint.toString() );
          }
          catch( final Exception e )
          {
              final String message =
                  "Could not set up Component for hint: " + hint;
              getLogger().error( message, e);
              throw new ComponentException( message, 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( final String hint, final Object instance )
      {
          try
          {
              final DefaultComponentHandler handler =
                  new DefaultComponentHandler( (Component)instance );
              handler.setLogger( getLogger() );
              handler.init();
              m_componentHandlers.put( hint, handler );
              getLogger().debug( "Adding " + instance.getClass().getName() + " for " + hint.toString() );
          }
          catch( final Exception e )
          {
              getLogger().error( "Could not set up Component for hint: " + hint, e );
          }
      }
  
      /**
       * 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( null != m_configuration &&
              !m_configuration.getName().equals( "" ) )
          {
              return m_configuration.getName();
          }
  
          return DEFAULT_NAME;
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/java/org/apache/excalibur/component/DefaultRoleManager.java
  
  Index: DefaultRoleManager.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 file.
   */
  package org.apache.excalibur.component;
  
  import java.util.Collections;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.Map;
  import org.apache.avalon.configuration.Configurable;
  import org.apache.avalon.configuration.Configuration;
  import org.apache.avalon.configuration.ConfigurationException;
  import org.apache.avalon.logger.AbstractLoggable;
  
  /**
   * Default RoleManager implementation.  It populates the RoleManager
   * from a configuration file.
   *
   * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
   * @author <a href="mailto:ricardo@apache,org">Ricardo Rocha</a>
   * @author <a href="mailto:giacomo@apache,org">Giacomo Pati</a>
   * @version CVS $Revision: 1.1 $ $Date: 2001/04/18 13:16:36 $
   */
  public class DefaultRoleManager 
      extends AbstractLoggable 
      implements RoleManager, Configurable
  {
      private Map  m_shorthands;
      private Map  m_classNames;
      private Map  m_hintClassNames;
  
      public final String getRoleForName( final String shorthandName )
      {
          final String role = (String)m_shorthands.get( shorthandName );
  
          getLogger().debug( "looking up shorthand " + shorthandName + 
                             ", returning " + role );
  
          return role;
      }
  
      public final String getDefaultClassNameForRole( final String role )
      {
          return (String)m_classNames.get( role );
      }
  
      public final String getDefaultClassNameForHint( final String role, 
                                                      final String shorthand )
      {
          getLogger().debug( "looking up hintmap for role " + role );
  
          final Map hintMap = (Map)m_hintClassNames.get( role );
  
          if( null == hintMap )
          {
              return "";
          }
  
          getLogger().debug( "looking up classname for hint " + shorthand );
          return (String)hintMap.get( shorthand );
      }
  
      public final void configure( final Configuration configuration ) 
          throws ConfigurationException
      {
          final Map shorts = new HashMap();
          final Map classes = new HashMap();
          final Map hintclasses = new HashMap();
  
          final Configuration[] roles = configuration.getChildren( "role" );
  
          for( int i = 0; i < roles.length; i++ )
          {
              final String name = roles[ i ].getAttribute( "name" );
              final String shorthand = roles[ i ].getAttribute( "shorthand" );
              final String defaultClassName = 
                  roles[ i ].getAttribute( "default-class", null );
  
              shorts.put( shorthand, name );
  
              if( null != defaultClassName )
              {
                  classes.put( name, defaultClassName );
              }
  
              final Configuration[] hints = roles[ i ].getChildren( "hint" );
              if( hints.length > 0 )
              {
                  HashMap hintMap = new HashMap();
  
                  for( int j = 0; j < hints.length; j++ )
                  {
                      final String shortHand = hints[ j ].getAttribute("shorthand").trim();
                      final String className = hints[ j ].getAttribute("class").trim();
  
                      hintMap.put( shortHand, className );
                      getLogger().debug( "Adding hint type " + shortHand + " associated with role " + 
                                         name + " and class " + className );
                  }
                  
                  hintclasses.put( name, Collections.unmodifiableMap( hintMap ) );
              }
  
              getLogger().debug( "added Role " + name + " with shorthand " +
                                 shorthand + " for " + defaultClassName );
          }
  
          m_shorthands = Collections.unmodifiableMap( shorts );
          m_classNames = Collections.unmodifiableMap( classes );
          m_hintClassNames = Collections.unmodifiableMap( hintclasses );
      }
  }
  
  
  
  1.1                  jakarta-avalon/src/java/org/apache/excalibur/component/RoleManager.java
  
  Index: RoleManager.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 file.
   */
  package org.apache.excalibur.component;
  
  import java.util.Iterator;
  
  /**
   * RoleManager Interface, use this to specify the Roles and how they
   * correspond easy shorthand names.
   *
   * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
   * @author <a href="mailto:ricardo@apache,org">Ricardo Rocha</a>
   * @author <a href="mailto:giacomo@apache,org">Giacomo Pati</a>
   * @version CVS $Revision: 1.1 $ $Date: 2001/04/18 13:16:36 $
   */
  public interface RoleManager
  {
      /**
       * Find Role name based on shorthand name.  Please note that if
       * this returns <code>null</code> or an empty string, then the
       * shorthand name is assumed to be a "reserved word".  In other
       * words, you should not try to instantiate a class from an empty
       * role.
       */
      String getRoleForName( String shorthandName );
  
      /**
       * Get the default classname for a given role.
       */
      String getDefaultClassNameForRole( String role );
  
      /**
       * Get the default classname for a given hint type.  This is only
       * used by ComponentSelectors.
       */
      String getDefaultClassNameForHint( String hint, String shorthand );
  }
  
  
  

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