mcconnell 2002/07/12 03:22:06
Added: assembly/src/java/org/apache/excalibur/merlin/kernel
TypeTable.java TypeRegistry.java
Log:
moved from registry to kernel and incorporated into classloader
Revision Changes Path
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/TypeTable.java
Index: TypeTable.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.excalibur.merlin.kernel;
import java.util.List;
import java.util.LinkedList;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.excalibur.meta.info.ServiceDesignator;
import org.apache.excalibur.meta.info.Type;
/**
* Internal table that holds references to the available component types
* that represent candidate providers for a single service type.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/12 10:22:05 $
*/
final class TypeTable extends AbstractLogEnabled
{
//=======================================================================
// state
//=======================================================================
/**
* Component type lists keyed by service designator.
*/
private List m_providers = new LinkedList();
/**
* Identification of the service type that this table is supporting.
*/
private ServiceDesignator m_designator;
public TypeTable( ServiceDesignator designator, Logger logger )
{
m_designator = designator;
super.enableLogging( logger );
}
//=======================================================================
// ServiceTable
//=======================================================================
/**
* Add a service provider to the set of provider managed by this table.
*
* @param classname the component class name
* @return the component type
*/
public void add( Type type )
{
m_providers.add( type );
}
/**
* Returns the set of providers currently registered in the table.
* @return the set of component types capable of acting as a provider for the
* service managed by the table
*/
public Type[] getTypes()
{
return (Type[]) m_providers.toArray( new Type[0] );
}
/**
* Return the service type for the table.
* @return the service designator
*/
public ServiceDesignator getService()
{
return m_designator;
}
/**
* Return the number of entries in the table.
* @return the number of providers
*/
public int getSize()
{
return m_providers.size();
}
/**
* Returns true if the table service designator matches the supplied designator.
* @param service a service type designator
* @return TRUE if the supplied service type matches the the service type for
* this table.
*/
public boolean matches( ServiceDesignator service )
{
return m_designator.matches( service );
}
public String toString()
{
return "TypeTable:"
+ System.identityHashCode( this )
+ ", "
+ m_designator;
}
}
1.1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/TypeRegistry.java
Index: TypeRegistry.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.excalibur.merlin.kernel;
import java.util.List;
import java.util.LinkedList;
import java.util.Hashtable;
import java.util.Vector;
import java.util.Iterator;
import org.apache.avalon.framework.CascadingException;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.logger.LogEnabled;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.excalibur.meta.info.ServiceDescriptor;
import org.apache.excalibur.meta.info.ServiceDesignator;
import org.apache.excalibur.meta.info.DependencyDescriptor;
import org.apache.excalibur.meta.info.Type;
import org.apache.excalibur.meta.info.builder.TypeBuilder;
import org.apache.excalibur.merlin.meta.data.Profile;
import org.apache.excalibur.merlin.meta.data.Selector;
import org.apache.excalibur.meta.verifier.ComponentVerifier;
import org.apache.excalibur.configuration.ConfigurationUtil;
/**
* Internal table that holds available component type keyed relative
* to the service it provides.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2002/07/12 10:22:05 $
*/
public final class TypeRegistry extends AbstractLogEnabled
{
//=======================================================================
// state
//=======================================================================
private TypeBuilder m_infoBuilder = new TypeBuilder();
private ClassLoader m_classloader;
/**
* Component types keyed by classname.
*/
private Hashtable m_types = new Hashtable();
/**
* List of TypeTable instances.
*/
private List m_services = new LinkedList();
//=======================================================================
// constructor
//=======================================================================
/**
* Creation of a new service registry.
* @param registry the registry that will be supplied to new component defintions
* @param loader the registry class loader
* @param profiles the configuration fragment containing explicit component
profiles
*/
public TypeRegistry( ClassLoader loader )
{
m_classloader = loader;
}
//=======================================================================
// LogEnabled
//=======================================================================
/**
* Set the logging channel for the service registry.
* @param logger the logging channel
*/
public void enableLogging( Logger logger )
{
super.enableLogging( logger );
m_infoBuilder.enableLogging( logger.getChildLogger("builder") );
}
//=======================================================================
// implemetation (TypeManager handler)
//=======================================================================
/**
* Resolve a {@link Type} from a classname.
*
* @param classname the component type
* @return the component type
*/
public Type lookup( String classname ) throws Exception
{
return register( classname );
}
/**
* Register a potential supplier component type. The implementation will
* create a component type instance for the entry if not already known and
* return the existing or new instance to the invoking client.
*
* @param classname the component class name
* @return the component type
*/
public Type register( String classname ) throws Exception
{
Type type = getType( classname );
if( type == null )
{
type = m_infoBuilder.build( classname, m_classloader );
String name = type.getInfo().getName();
Class clazz = getComponentClass( type );
Class[] classes = getServiceClasses( type );
ComponentVerifier verifier = new ComponentVerifier();
verifier.enableLogging( getLogger().getChildLogger( "verifier" ));
verifier.verifyComponent( name, clazz, classes );
register( type );
}
return type;
}
//=======================================================================
// TypeRegistry (private)
//=======================================================================
private Class[] getServiceClasses( Type type )
{
Vector vector = new Vector();
ServiceDescriptor[] services = type.getServices();
for( int i=0; i<services.length; i++ )
{
vector.add( getServiceClass( services[i] ) );
}
return (Class[]) vector.toArray( new Class[0] );
}
/**
* Returns the component type implementation class.
* @param type the component type descriptor
* @return the class implementing the component type
*/
private Class getComponentClass( Type type ) throws KernelException
{
if( null == type )
throw new NullPointerException("Illegal null component type argument.");
final String classname = type.getInfo().getImplementationKey();
try
{
return m_classloader.loadClass( classname );
}
catch( Throwable e )
{
final String error = "Could not load implementation class for component
type: "
+ classname;
throw new KernelException( error, e );
}
}
/**
* Returns the service type implementation class.
* @param service the service type descriptor
* @return the class implementing the service type
*/
private Class getServiceClass( ServiceDescriptor service ) throws
KernelRuntimeException
{
final String classname = service.getService().getClassname();
try
{
return m_classloader.loadClass( classname );
}
catch( Throwable e )
{
final String error = "Could not load implementation class for service
type: "
+ classname;
throw new KernelRuntimeException( error, e );
}
}
/**
* Returns the set of component types know to the registry.
* @return the set of component types registered with the registry
*/
public Type[] getTypes()
{
return (Type[]) m_types.values().toArray( new Type[0] );
}
/**
* Returns the set of component types know to the registry that are capable of
* supporting the supplied service.
* @return the set of candidate component types
*/
public Type[] getTypes( ServiceDesignator service )
{
return getTable( service ).getTypes();
}
/**
* Returns a registered component type.
* @return the component type from the registry or null if the type is unknown
*/
public Type getType( String classname )
{
return (Type) m_types.get( classname );
}
/**
* Register the type resulting in the cross-referencing of the type with the set
of
* service tables that the type is is capable of supporting.
*/
private void register( Type type )
{
String key = type.getInfo().getImplementationKey();
m_types.put( key, type );
getLogger().debug( "Type: '" + key + "' registered.");
ServiceDescriptor[] services = type.getServices();
for( int i=0; i<services.length; i++ )
{
register( services[i].getService(), type );
}
}
/**
* Register a type under a service cross-reference.
*/
private void register( ServiceDesignator service, Type type )
{
TypeTable table = getTable( service );
table.add( type );
}
/**
* Return a table holding table capable of supply the supplied service.
*/
private TypeTable getTable( ServiceDesignator service )
{
TypeTable table = null;
Iterator iterator = m_services.iterator();
while( iterator.hasNext() )
{
table = (TypeTable) iterator.next();
if( table.matches( service ) )
return table;
}
// otherwise create a new table
table = new TypeTable( service, getLogger().getChildLogger("table") );
m_services.add( table );
return table;
}
}
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>