donaldp 2002/10/01 00:04:05
Modified: src/java/org/apache/avalon/phoenix/components/application
BlockResourceProvider.java DefaultApplication.java
src/java/org/apache/avalon/phoenix/metadata
DependencyMetaData.java
src/java/org/apache/avalon/phoenix/metainfo
ServiceDescriptor.java
src/java/org/apache/avalon/phoenix/tools/assembler
Assembler.java
Log:
Start providing basic support for dependencies that are either;
* an array of services of a particular type
* a map of services of a particular type
ie It is now possible for a block to declare that it will accept a map of "Foo"
services and the assembler will be able to map 0-N different Foo services into map. An
assembler could also map 0-N services of type Foo onto a dependency if it is an array
dependency.
Array dependencies have postfix "[]" while maps have a postfix "#"
Revision Changes Path
1.7 +120 -15
jakarta-avalon-phoenix/src/java/org/apache/avalon/phoenix/components/application/BlockResourceProvider.java
Index: BlockResourceProvider.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-phoenix/src/java/org/apache/avalon/phoenix/components/application/BlockResourceProvider.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- BlockResourceProvider.java 6 Sep 2002 12:01:07 -0000 1.6
+++ BlockResourceProvider.java 1 Oct 2002 07:04:05 -0000 1.7
@@ -24,7 +24,15 @@
import org.apache.avalon.phoenix.interfaces.ApplicationContext;
import org.apache.avalon.phoenix.metadata.BlockMetaData;
import org.apache.avalon.phoenix.metadata.DependencyMetaData;
+import org.apache.avalon.phoenix.metainfo.DependencyDescriptor;
+import org.apache.avalon.phoenix.metainfo.ServiceDescriptor;
import org.apache.excalibur.containerkit.lifecycle.ResourceProvider;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.lang.reflect.Array;
/**
* The accessor used to access resources for a particular
@@ -128,29 +136,30 @@
throws Exception
{
final BlockMetaData metaData = getMetaDataFor( entry );
- final DefaultComponentManager componentManager = new
DefaultComponentManager();
- final DependencyMetaData[] roles = metaData.getDependencies();
+ final DefaultComponentManager manager = new DefaultComponentManager();
- for( int i = 0; i < roles.length; i++ )
+ final Map serviceMap = createServiceMap( entry );
+ final Iterator iterator = serviceMap.keySet().iterator();
+ while( iterator.hasNext() )
{
- final DependencyMetaData role = roles[ i ];
- final Object dependency = m_application.getBlock( role.getName() );
- if( dependency instanceof Component )
+ final String key = (String) iterator.next();
+ final Object value = serviceMap.get( key );
+ if( value instanceof Component )
{
- componentManager.put( role.getRole(), (Component)dependency );
+ manager.put( key, (Component) value );
}
else
{
final String message =
REZ.getString( "lifecycle.nota-component.error",
metaData.getName(),
- role.getRole(),
- role.getName() );
+ key,
+ metaData.getDependency( key ).getName() );
throw new Exception( message );
}
}
- return componentManager;
+ return manager;
}
/**
@@ -166,18 +175,114 @@
public ServiceManager createServiceManager( final Object entry )
throws Exception
{
- final BlockMetaData metaData = getMetaDataFor( entry );
+ final Map serviceMap = createServiceMap( entry );
final DefaultServiceManager manager = new DefaultServiceManager();
+
+ final Iterator iterator = serviceMap.keySet().iterator();
+ while( iterator.hasNext() )
+ {
+ final String key = (String) iterator.next();
+ final Object value = serviceMap.get( key );
+ manager.put( key, value );
+ }
+
+ return manager;
+ }
+
+ private Map createServiceMap( final Object entry )
+ throws Exception
+ {
+ final BlockMetaData metaData = getMetaDataFor( entry );
+ final HashMap map = new HashMap();
+ final HashMap sets = new HashMap();
+
final DependencyMetaData[] roles = metaData.getDependencies();
for( int i = 0; i < roles.length; i++ )
{
final DependencyMetaData role = roles[ i ];
final Object dependency = m_application.getBlock( role.getName() );
- manager.put( role.getRole(), dependency );
+
+ final DependencyDescriptor candidate =
+ metaData.getBlockInfo().getDependency( role.getRole() );
+
+ final String key = role.getRole();
+
+ final ServiceDescriptor service = candidate.getService();
+ if( service.isArray() )
+ {
+ ArrayList list = (ArrayList) sets.get( key );
+ if( null == list )
+ {
+ list = new ArrayList();
+ sets.put( key, list );
+ }
+
+ list.add( dependency );
+ }
+ else if( service.isMap() )
+ {
+ HashMap smap = (HashMap) sets.get( key );
+ if( null == smap )
+ {
+ smap = new HashMap();
+ sets.put( key, smap );
+ }
+
+ map.put( role.getAlias(), dependency );
+ }
+ else
+ {
+ map.put( key, dependency );
+ }
}
- return manager;
+ final Iterator iterator = sets.keySet().iterator();
+ while( iterator.hasNext() )
+ {
+ final String key = (String) iterator.next();
+ final Object value = sets.get( key );
+ if( value instanceof List )
+ {
+ final List list = (List) value;
+ final ServiceDescriptor service =
+ metaData.getBlockInfo().getDependency( key ).getService();
+
+ final String classname =
+ "[L" + service.getComponentType() + ";";
+
+ final Object[] result = toArray( list, service.getComponentType() );
+ map.put( key, result );
+ map.put( classname, result );
+ }
+ else
+ {
+ map.put( key, value );
+ }
+ }
+
+ return map;
+ }
+
+ /**
+ * Convert specified list into array of specified type.
+ * Note that the class for the type must be loaded from same
+ * classloader as the elements in the list are loaded from.
+ *
+ * @param list the list
+ * @param type the classname of type
+ * @return array of objects that are in list
+ * @throws ClassNotFoundException if unable to find correct type
+ */
+ private Object[] toArray( final List list, final String type )
+ throws ClassNotFoundException
+ {
+ final ClassLoader classLoader =
+ list.get( 0 ).getClass().getClassLoader();
+ final Class clazz = classLoader.loadClass( type );
+ final Object[] elements =
+ (Object[]) Array.newInstance( clazz, list.size() );
+ return list.toArray( elements );
}
public Configuration createConfiguration( final Object entry )
@@ -219,6 +324,6 @@
*/
private BlockMetaData getMetaDataFor( final Object entry )
{
- return ((BlockEntry)entry).getMetaData();
+ return ( (BlockEntry) entry ).getMetaData();
}
}
1.37 +3 -3
jakarta-avalon-phoenix/src/java/org/apache/avalon/phoenix/components/application/DefaultApplication.java
Index: DefaultApplication.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-phoenix/src/java/org/apache/avalon/phoenix/components/application/DefaultApplication.java,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -r1.36 -r1.37
--- DefaultApplication.java 6 Sep 2002 12:01:07 -0000 1.36
+++ DefaultApplication.java 1 Oct 2002 07:04:05 -0000 1.37
@@ -464,7 +464,7 @@
/**
* Method to run a Block through it's startup phase.
- * This will involve notification of {@link BlockListener}
+ * This will involve notification of {@link ApplicationListener}
* objects, creation of the Block/Block Proxy object, calling the startup
* Avalon Lifecycle methods and updating State property of BlockEntry.
* Errors that occur during shutdown will be logged appropriately and
@@ -493,7 +493,7 @@
/**
* Method to run a Block through it's shutdown phase.
- * This will involve notification of {@link BlockListener}
+ * This will involve notification of {@link ApplicationListener}
* objects, invalidating the proxy object, calling the shutdown
* Avalon Lifecycle methods and updating State property of BlockEntry.
* Errors that occur during shutdown will be logged appropraitely.
@@ -524,7 +524,7 @@
}
/**
- * Method to run a {@link BlockListener} through it's startup phase.
+ * Method to run a {@link ApplicationListener} through it's startup phase.
* This will involve creation of BlockListener object and configuration of
* object if appropriate.
*
1.7 +10 -2
jakarta-avalon-phoenix/src/java/org/apache/avalon/phoenix/metadata/DependencyMetaData.java
Index: DependencyMetaData.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-phoenix/src/java/org/apache/avalon/phoenix/metadata/DependencyMetaData.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- DependencyMetaData.java 6 Aug 2002 11:57:41 -0000 1.6
+++ DependencyMetaData.java 1 Oct 2002 07:04:05 -0000 1.7
@@ -15,12 +15,15 @@
public final class DependencyMetaData
{
private final String m_name;
-
private final String m_role;
+ private final String m_alias;
- public DependencyMetaData( final String name, final String role )
+ public DependencyMetaData( final String name,
+ final String role,
+ final String alias )
{
m_name = name;
+ m_alias = alias;
m_role = role;
}
@@ -32,5 +35,10 @@
public String getName()
{
return m_name;
+ }
+
+ public String getAlias()
+ {
+ return m_alias;
}
}
1.13 +51 -1
jakarta-avalon-phoenix/src/java/org/apache/avalon/phoenix/metainfo/ServiceDescriptor.java
Index: ServiceDescriptor.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-phoenix/src/java/org/apache/avalon/phoenix/metainfo/ServiceDescriptor.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- ServiceDescriptor.java 30 Sep 2002 12:36:31 -0000 1.12
+++ ServiceDescriptor.java 1 Oct 2002 07:04:05 -0000 1.13
@@ -18,6 +18,9 @@
*/
public final class ServiceDescriptor
{
+ public static final String ARRAY_POSTFIX = "[]";
+ public static final String MAP_POSTFIX = "#";
+
private final Version m_version;
private final String m_name;
@@ -55,6 +58,52 @@
}
/**
+ * Return the type of component type if the service
+ * is an array or Map Service. Otherwise just return the
+ * name of service.
+ *
+ * @return the Service component type
+ */
+ public String getComponentType()
+ {
+ final String fullname = getName();
+ if( isArray() )
+ {
+ final int end = fullname.length() - ARRAY_POSTFIX.length();
+ return fullname.substring( 0, end );
+ }
+ else if( isMap() )
+ {
+ final int end = fullname.length() - MAP_POSTFIX.length();
+ return fullname.substring( 0, end );
+ }
+ else
+ {
+ return fullname;
+ }
+ }
+
+ /**
+ * Return true if Service name designates an array of services.
+ *
+ * @return true if Service name designates an array of services.
+ */
+ public boolean isArray()
+ {
+ return m_name.endsWith( ARRAY_POSTFIX );
+ }
+
+ /**
+ * Return true if Service name designates an map of services.
+ *
+ * @return true if Service name designates an map of services.
+ */
+ public boolean isMap()
+ {
+ return m_name.endsWith( MAP_POSTFIX );
+ }
+
+ /**
* Determine if specified service will match this service.
* To match a service has to have same name and must comply with version.
*
@@ -63,8 +112,9 @@
*/
public boolean matches( final ServiceDescriptor other )
{
+ final String name = getComponentType();
return
- other.getName().equals( m_name )
+ other.getName().equals( name )
&& other.getVersion().complies( m_version );
}
1.22 +3 -2
jakarta-avalon-phoenix/src/java/org/apache/avalon/phoenix/tools/assembler/Assembler.java
Index: Assembler.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-phoenix/src/java/org/apache/avalon/phoenix/tools/assembler/Assembler.java,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- Assembler.java 1 Oct 2002 06:21:37 -0000 1.21
+++ Assembler.java 1 Oct 2002 07:04:05 -0000 1.22
@@ -242,9 +242,10 @@
{
final Configuration provide = provides[ j ];
final String requiredName = provide.getAttribute( "name" );
+ final String alias = provide.getAttribute( "alias", requiredName );
final String role = provide.getAttribute( "role" );
- dependencies.add( new DependencyMetaData( requiredName, role ) );
+ dependencies.add( new DependencyMetaData( requiredName, role, alias ) );
}
return (DependencyMetaData[])dependencies.toArray( new DependencyMetaData[
0 ] );
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>