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