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]>

Reply via email to