avalon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dona...@apache.org
Subject cvs commit: jakarta-avalon-excalibur/containerkit/src/java/org/apache/excalibur/containerkit/kernel Resources.properties KernelResourceAccessor.java
Date Tue, 18 Jun 2002 03:41:49 GMT
donaldp     2002/06/17 20:41:49

  Modified:    containerkit/src/java/org/apache/excalibur/containerkit/kernel
                        KernelResourceAccessor.java
  Added:       containerkit/src/java/org/apache/excalibur/containerkit/kernel
                        Resources.properties
  Log:
  Update Accessor to be more fully implemented
  
  Revision  Changes    Path
  1.2       +250 -31   jakarta-avalon-excalibur/containerkit/src/java/org/apache/excalibur/containerkit/kernel/KernelResourceAccessor.java
  
  Index: KernelResourceAccessor.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/containerkit/src/java/org/apache/excalibur/containerkit/kernel/KernelResourceAccessor.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- KernelResourceAccessor.java	14 Jun 2002 08:00:47 -0000	1.1
  +++ KernelResourceAccessor.java	18 Jun 2002 03:41:49 -0000	1.2
  @@ -8,40 +8,129 @@
   package org.apache.excalibur.containerkit.kernel;
   
   import java.util.HashMap;
  +import java.util.Iterator;
   import java.util.Map;
   import org.apache.avalon.excalibur.i18n.ResourceManager;
   import org.apache.avalon.excalibur.i18n.Resources;
  +import org.apache.avalon.framework.component.Component;
   import org.apache.avalon.framework.component.ComponentManager;
  +import org.apache.avalon.framework.component.DefaultComponentManager;
  +import org.apache.avalon.framework.configuration.Configuration;
   import org.apache.avalon.framework.context.Context;
  +import org.apache.avalon.framework.context.DefaultContext;
  +import org.apache.avalon.framework.logger.AbstractLogEnabled;
  +import org.apache.avalon.framework.parameters.Parameters;
  +import org.apache.avalon.framework.service.DefaultServiceManager;
   import org.apache.avalon.framework.service.ServiceManager;
   import org.apache.excalibur.containerkit.lifecycle.ResourceAccessor;
   import org.apache.excalibur.containerkit.metadata.ComponentMetaData;
  +import org.apache.excalibur.containerkit.metadata.DependencyMetaData;
  +import org.apache.excalibur.containerkit.metainfo.ComponentInfo;
   import org.apache.excalibur.containerkit.metainfo.ContextDescriptor;
   import org.apache.excalibur.containerkit.metainfo.EntryDescriptor;
   
   /**
  + * This is the bas object via which the kernel aquires
  + * resources for each component. This base implementation
  + * will aquire components and make sure that all required
  + * components are present. It will also make sure that the types
  + * of values returned from context are valid.
    *
  + * <p>Note that this class assumes that the dependency graph
  + * has been validated (presumably via
  + * {@link org.apache.excalibur.containerkit.verifier.AssemblyVerifier}</p>
    *
    * @author <a href="mailto:peter@apache.org">Peter Donald</a>
    * @version $Revision$ $Date$
    */
   public abstract class KernelResourceAccessor
  +    extends AbstractLogEnabled
       implements ResourceAccessor
   {
       private final static Resources REZ =
           ResourceManager.getPackageResources( KernelResourceAccessor.class );
   
  -    private final AbstractServiceKernel m_kernel;
  +    /**
  +     * Utility method via which the {@link KernelResourceAccessor)
  +     * aquires services to place in ServiceManager for a particular
  +     * component.
  +     *
  +     * <p>Must be implemented in subclass.</p>
  +     *
  +     * @param name the name of service
  +     * @param entry the entry for component aquiring service
  +     * @return the service object for specified name
  +     */
  +    protected abstract Object getService( String name, Object entry );
  +
  +    /**
  +     * Utility method via which the {@link KernelResourceAccessor)
  +     * aquires a context value to place in Context for a particular
  +     * component.
  +     *
  +     * <p>Must be implemented in subclass.</p>
  +     *
  +     * @param name the name of service
  +     * @param entry the entry for component aquiring service
  +     * @return the context value for specified name
  +     */
  +    protected abstract Object getContextValue( String name, Object entry );
   
  -    public KernelResourceAccessor( final AbstractServiceKernel kernel )
  +    /**
  +     * Create a Parameters object by Creating configuration object and converting that.
  +     *
  +     * @param entry the entry
  +     * @return a new Parameters object for component
  +     * @throws Exception if unable to create resource
  +     */
  +    public Parameters createParameters( Object entry )
  +        throws Exception
  +    {
  +        final Configuration configuration = createConfiguration( entry );
  +        return Parameters.fromConfiguration( configuration );
  +    }
  +
  +    /**
  +     * Create a {@link Context} object that contains values specified in map.
  +     * The default implementation creates a basic Context object but different
  +     * containers may choose to overide this to provide their own subclass of context.
  +     *
  +     * @param contextData the data to place in context
  +     * @return the Context object
  +     */
  +    protected Context createContextImpl( final Map contextData )
  +    {
  +        final DefaultContext context = new DefaultContext( contextData );
  +        context.makeReadOnly();
  +        return context;
  +    }
  +
  +    /**
  +     * Return the {@link ComponentMetaData} for specified component entry.
  +     * This implementation assumes that entry is instance of {@link ComponentMetaData}
  +     * but subclasses should overide this method if this assumption does not hold true.
  +     *
  +     * @param entry the component entry
  +     * @return the ComponentMetaData
  +     */
  +    protected ComponentMetaData getMetaData( final Object entry )
       {
  -        m_kernel = kernel;
  +        return (ComponentMetaData)entry;
       }
   
  -    public Context createContext( Object entry )
  +    /**
  +     * Create a context object for specified component.
  +     *
  +     * @param componentEntry the entry representing component
  +     * @return the created Context
  +     * @throws Exception if unable to create context or entrys in context
  +     */
  +    public final Context createContext( final Object componentEntry )
           throws Exception
       {
  -        final ComponentMetaData component = getMetaData( entry );
  +        final ComponentMetaData component = getMetaData( componentEntry );
  +        final String componentName = component.getName();
  +
           final ContextDescriptor descriptor =
               component.getComponentInfo().getContextDescriptor();
   
  @@ -50,49 +139,70 @@
           final EntryDescriptor[] entrys = descriptor.getEntrys();
           for( int i = 0; i < entrys.length; i++ )
           {
  -            final String key = entrys[ i ].getKey();
  -            final String type = entrys[ i ].getType();
  -            final boolean optional = entrys[ i ].isOptional();
  +            final EntryDescriptor entry = entrys[ i ];
  +            final String key = entry.getKey();
  +            final String type = entry.getType();
  +            final boolean optional = entry.isOptional();
               final Object value =
  -                m_kernel.getContextValue( key, entry );
  -
  +                getContextValue( key, componentEntry );
   
  -            if( null == value && !optional )
  +            if( null == value )
               {
  +                final String message =
  +                    REZ.getString( "resource.missing-context-value.error",
  +                                   optional ? "1" : "2",
  +                                   key,
  +                                   componentName );
                   if( !optional )
                   {
  -                    final String message =
  -                        REZ.getString( "resource.missing-context-value.error",
  -                                       key,
  -                                       component.getName() );
                       throw new Exception( message );
                   }
                   else
                   {
  +                    getLogger().warn( message );
                       continue;
                   }
               }
   
  -            final Class clazz = value.getClass();
  -            final Class typeClass = clazz.getClassLoader().loadClass( type );
  -            if( !typeClass.isAssignableFrom( clazz ) )
  +            final boolean typeValid = objectImplementsType( value, type );
  +            if( !typeValid )
               {
                   final String message =
                       REZ.getString( "resource.bad-value-type.error",
  +                                   optional ? "1" : "2",
                                      key,
  +                                   componentName,
                                      type,
  -                                   clazz.getName(),
  -                                   component.getName() );
  -                throw new Exception( message );
  +                                   value.getClass().getName() );
  +                if( !optional )
  +                {
  +                    throw new Exception( message );
  +                }
  +                else
  +                {
  +                    getLogger().warn( message );
  +                    continue;
  +                }
               }
  +
  +            contextData.put( key, value );
           }
   
  -        return null;
  -    }
  +        final Context context = createContextImpl( contextData );
  +        final String classname = descriptor.getClassname();
   
  -    protected ComponentMetaData getMetaData( final Object entry )
  -    {
  -        return (ComponentMetaData)entry;
  +        final boolean validContextClass = objectImplementsType( context, classname );
  +        if( !validContextClass )
  +        {
  +            final String message =
  +                REZ.getString( "resource.bad-context-type.error",
  +                               classname,
  +                               context.getClass().getName(),
  +                               componentName );
  +            throw new Exception( message );
  +        }
  +
  +        return context;
       }
   
       /**
  @@ -102,10 +212,31 @@
        * @return a new ComponentManager for component
        * @throws Exception if unable to create resource
        */
  -    public ComponentManager createComponentManager( Object entry )
  +    public final ComponentManager createComponentManager( final Object entry )
           throws Exception
       {
  -        return null;
  +        final Map services = createServiceMap( entry );
  +
  +        final DefaultComponentManager componentManager = new DefaultComponentManager();
  +
  +        final Iterator keys = services.keySet().iterator();
  +        while( keys.hasNext() )
  +        {
  +            final String key = (String)keys.next();
  +            final Object service = services.get( key );
  +            if( !Component.class.isInstance( service ) )
  +            {
  +                final String message =
  +                    REZ.getString( "resource.service-not-a-component.error",
  +                                   key,
  +                                   service.getClass().getName() );
  +                throw new Exception( message );
  +            }
  +            componentManager.put( key, (Component)service );
  +        }
  +
  +        componentManager.makeReadOnly();
  +        return componentManager;
       }
   
       /**
  @@ -115,9 +246,97 @@
        * @return a new ServiceManager for component
        * @throws Exception if unable to create resource
        */
  -    public ServiceManager createServiceManager( Object entry )
  +    public final ServiceManager createServiceManager( final Object entry )
           throws Exception
       {
  -        return null;
  +        final Map services = createServiceMap( entry );
  +
  +        final DefaultServiceManager serviceManager = new DefaultServiceManager();
  +
  +        final Iterator keys = services.keySet().iterator();
  +        while( keys.hasNext() )
  +        {
  +            final String key = (String)keys.next();
  +            final Object service = services.get( key );
  +            serviceManager.put( key, service );
  +        }
  +
  +        serviceManager.makeReadOnly();
  +        return serviceManager;
  +    }
  +
  +    /**
  +     * Create a Map of services for specified component.
  +     * The map maps role name to service provider.
  +     *
  +     * @param componentEntry the component entry creating map for
  +     * @return the map
  +     * @throws Exception if error aquiring a service to place in map
  +     */
  +    private Map createServiceMap( final Object componentEntry )
  +        throws Exception
  +    {
  +        final ComponentMetaData component = getMetaData( componentEntry );
  +        final ComponentInfo info = component.getComponentInfo();
  +        final DependencyMetaData[] dependencies = component.getDependencies();
  +
  +        final HashMap services = new HashMap();
  +
  +        for( int i = 0; i < dependencies.length; i++ )
  +        {
  +            final DependencyMetaData dependency = dependencies[ i ];
  +            final String role = dependency.getRole();
  +            final String providerName = dependency.getProviderName();
  +            final boolean optional = info.getDependency( role ).isOptional();
  +
  +            final Object service =
  +                getService( providerName, componentEntry );
  +            if( null == service )
  +            {
  +                final String message =
  +                    REZ.getString( "resource.missing-dependency.error",
  +                                   optional ? "1" : "2",
  +                                   role,
  +                                   component.getName() );
  +                if( !optional )
  +                {
  +                    throw new Exception( message );
  +                }
  +                else
  +                {
  +                    getLogger().warn( message );
  +                    continue;
  +                }
  +            }
  +
  +            services.put( role, service );
  +        }
  +
  +        return services;
  +    }
  +
  +    /**
  +     * Check whether the specified value is compatible with specified type.
  +     *
  +     * @param value the value
  +     * @param type the desired type
  +     * @return true if value is compatible with type, false otherwise
  +     */
  +    private boolean objectImplementsType( final Object value, final String type )
  +    {
  +        try
  +        {
  +            final Class clazz = value.getClass();
  +            final ClassLoader classLoader = clazz.getClassLoader();
  +            final Class typeClass = classLoader.loadClass( type );
  +            if( typeClass.isAssignableFrom( clazz ) )
  +            {
  +                return true;
  +            }
  +        }
  +        catch( final ClassNotFoundException cnfe )
  +        {
  +        }
  +        return false;
       }
   }
  
  
  
  1.1                  jakarta-avalon-excalibur/containerkit/src/java/org/apache/excalibur/containerkit/kernel/Resources.properties
  
  Index: Resources.properties
  ===================================================================
  resource.missing-context-value.error=Missing {0,choice,1#Optional|2#Required} Context Entry
with key "{1}" for component named "{2}".
  resource.bad-value-type.error=Bad value retrieved for {0,choice,1#Optional|2#Required} Context
Entry with key "{1}" for component named "{2}". Expected to be of type "{3}" but was of type
"{4}".
  resource.bad-context-type.error=The class of Contex object for component named "{2}" was
expected to be of type {0} but was of tpye {1}.
  resource.service-not-a-component.error=The service with role "0" and implemenation class
"{1}" does not implement the Component interface but is being exposed via ComponentManager.
  resource.missing-dependency.error=Missing {0,choice,1#Optional|2#Required} dependency with
role "{1}" for component named {2}.
  
  
  

--
To unsubscribe, e-mail:   <mailto:avalon-cvs-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:avalon-cvs-help@jakarta.apache.org>


Mime
View raw message