You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@avalon.apache.org by do...@apache.org on 2002/06/18 07:26:31 UTC

cvs commit: jakarta-avalon-excalibur/containerkit/src/java/org/apache/excalibur/containerkit/lifecycle/impl AbstractResourceProvider.java Resource.properties

donaldp     2002/06/17 22:26:31

  Added:       containerkit/src/java/org/apache/excalibur/containerkit/lifecycle/impl
                        AbstractResourceProvider.java Resource.properties
  Log:
  Move kernelResourceProvider to subpackage of lifecycle and rename it AbstractResourceProvider
  
  Revision  Changes    Path
  1.1                  jakarta-avalon-excalibur/containerkit/src/java/org/apache/excalibur/containerkit/lifecycle/impl/AbstractResourceProvider.java
  
  Index: AbstractResourceProvider.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.containerkit.lifecycle.impl;
  
  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.ResourceProvider;
  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 a base object via which the
   * {@link org.apache.excalibur.containerkit.lifecycle.LifecycleHelper}
   * 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: 1.1 $ $Date: 2002/06/18 05:26:31 $
   */
  public abstract class AbstractResourceProvider
      extends AbstractLogEnabled
      implements ResourceProvider
  {
      private final static Resources REZ =
          ResourceManager.getPackageResources( AbstractResourceProvider.class );
  
      /**
       * Utility method via which the provider 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 provider 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 );
  
      /**
       * Create a Parameters object by Creating configuration object and converting that.
       *
       * @param entry the entry
       * @return a new Parameters object for component
       * @throws java.lang.Exception if unable to create resource
       */
      public Parameters createParameters( Object entry )
          throws Exception
      {
          final Configuration configuration = createConfiguration( entry );
          final Parameters parameters = Parameters.fromConfiguration( configuration );
          parameters.makeReadOnly();
          return parameters;
      }
  
      /**
       * Create a {@link org.apache.avalon.framework.context.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 org.apache.excalibur.containerkit.metadata.ComponentMetaData} for specified component entry.
       * This implementation assumes that entry is instance of {@link org.apache.excalibur.containerkit.metadata.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 )
      {
          return (ComponentMetaData)entry;
      }
  
      /**
       * Create a context object for specified component.
       *
       * @param componentEntry the entry representing component
       * @return the created Context
       * @throws java.lang.Exception if unable to create context or entrys in context
       */
      public final Context createContext( final Object componentEntry )
          throws Exception
      {
          final ComponentMetaData component = getMetaData( componentEntry );
          final String componentName = component.getName();
  
          final ContextDescriptor descriptor =
              component.getComponentInfo().getContextDescriptor();
  
          final Map contextData = new HashMap();
  
          final EntryDescriptor[] entrys = descriptor.getEntrys();
          for( int i = 0; i < entrys.length; i++ )
          {
              final EntryDescriptor entry = entrys[ i ];
              final String key = entry.getKey();
              final String type = entry.getType();
              final boolean optional = entry.isOptional();
              final Object value =
                  getContextValue( key, componentEntry );
  
              if( null == value )
              {
                  final String message =
                      REZ.getString( "resource.missing-context-value.error",
                                     optional ? "1" : "2",
                                     key,
                                     componentName );
                  if( !optional )
                  {
                      throw new Exception( message );
                  }
                  else
                  {
                      getLogger().warn( message );
                      continue;
                  }
              }
  
              final boolean typeValid = objectImplementsType( value, type );
              if( !typeValid )
              {
                  final String message =
                      REZ.getString( "resource.bad-value-type.error",
                                     optional ? "1" : "2",
                                     key,
                                     componentName,
                                     type,
                                     value.getClass().getName() );
                  if( !optional )
                  {
                      throw new Exception( message );
                  }
                  else
                  {
                      getLogger().warn( message );
                      continue;
                  }
              }
  
              contextData.put( key, value );
          }
  
          final Context context = createContextImpl( contextData );
          final String classname = descriptor.getClassname();
  
          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;
      }
  
      /**
       * Create a new ComponentManager for component.
       *
       * @param entry the entry
       * @return a new ComponentManager for component
       * @throws java.lang.Exception if unable to create resource
       */
      public final ComponentManager createComponentManager( final Object entry )
          throws Exception
      {
          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;
      }
  
      /**
       * Create a new ServiceManager for component.
       *
       * @param entry the entry
       * @return a new ServiceManager for component
       * @throws java.lang.Exception if unable to create resource
       */
      public final ServiceManager createServiceManager( final Object entry )
          throws Exception
      {
          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 java.lang.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/lifecycle/impl/Resource.properties
  
  Index: Resource.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:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>