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

cvs commit: jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry ProfileRegistry.java ProfileTable.java TypeRegistry.java TypeTable.java ComponentDefinition.java ComponentType.java DefaultRegistry.xinfo Profile.java ServiceRegistry.java ServiceTable.java

mcconnell    2002/07/06 21:40:15

  Added:       assembly/src/java/org/apache/excalibur/merlin/registry
                        ProfileRegistry.java ProfileTable.java
                        TypeRegistry.java TypeTable.java
  Removed:     assembly/src/java/org/apache/excalibur/merlin/registry
                        ComponentDefinition.java ComponentType.java
                        DefaultRegistry.xinfo Profile.java
                        ServiceRegistry.java ServiceTable.java
  Log:
  rationalization of registry based on excalibur.meta.*
  
  Revision  Changes    Path
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/ProfileRegistry.java
  
  Index: ProfileRegistry.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.registry;
  
  import java.util.List;
  import java.util.ArrayList;
  import java.util.LinkedList;
  import java.util.Hashtable;
  import java.util.ArrayList;
  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.avalon.framework.activity.Startable;
  import org.apache.avalon.framework.activity.Initializable;
  import org.apache.avalon.framework.activity.Disposable;
  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.data.Profile;
  import org.apache.excalibur.meta.verifier.ComponentVerifier;
  import org.apache.excalibur.meta.builder.TypeBuilder;
  import org.apache.excalibur.meta.builder.ProfileBuilder;
  import org.apache.excalibur.configuration.ConfigurationUtil;
  import org.apache.excalibur.merlin.kernel.Map;
  import org.apache.excalibur.merlin.kernel.Container;
  
  /**
   * Internal table that holds available component type keyed relative
   * to the service it provides.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/07 04:40:15 $
   */
  final class ProfileRegistry extends AbstractLogEnabled implements Startable
  {
  
      //=======================================================================
      // state
      //=======================================================================
  
      private ProfileBuilder m_builder = new ProfileBuilder();
      private ClassLoader m_classloader;
      private TypeRegistry m_types;
      private Container m_parent;
  
     /**
      * Component profiles keyed by name.
      */
      private Hashtable m_profiles = new Hashtable();
  
     /**
      * List of ServiceTable instances.
      */
      private List m_services = new LinkedList();
  
      private final Configuration[] m_directives;
  
     /**
      * The set of local explicitly declared profiles.
      */
      private Vector m_assembly = new Vector();
  
     /**
      * The set of locally installed profiles.
      */
      private ArrayList m_installed = new ArrayList();
  
      private Map m_map;
  
     //=======================================================================
      // 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 ProfileRegistry( 
        Configuration[] directives, TypeRegistry registry, ClassLoader loader, Container parent, Map map )
      {
          m_classloader = loader;
          m_types = registry;
          m_directives = directives;
          m_parent = parent;
          m_map = map;
      }
  
      //======================================================================
      // Startable
      //======================================================================
  
      public void start() throws Exception
      {
          Profile[] startup = m_map.getStartupGraph();
          getLogger().debug("startup");
          for( int i=0; i<startup.length; i++ )
          {
              Profile profile = startup[i];
              if( isLocalProfile( profile ) )
                getLogger().debug("start: " + profile.getName() );
          }
      }
  
      public void stop()
      {
          Profile[] shutdown = m_map.getShutdownGraph();
          for( int i=0; i<shutdown.length; i++ )
          {
              Profile profile = shutdown[i];
              if( isLocalProfile( profile ) )
                getLogger().debug("stop: " + profile.getName() );
          }
      }
  
  
      //=======================================================================
      // PrifileRegistry
      //=======================================================================
  
      public Profile[] getProviders( ServiceDesignator designator )
      {
          ArrayList list = new ArrayList();
          Profile[] local = (Profile[]) m_installed.toArray( new Profile[0] );
          for( int i=0; i<local.length; i++ )
          {
              Profile profile = local[i];
              ServiceDescriptor[] services = profile.getType().getServices();
              for( int j=0; j<services.length; j++ )
              {
                  if( services[j].getServiceDesignator().matches( designator ) )
                  {
                     list.add( profile );
                     break;
                  } 
              }
          }
          return (Profile[]) list.toArray( new Profile[0] );
      }
  
      public int prepareProfiles() throws Exception
      {
          prepareDirectives();
          prepareTypes();
          return getProfiles().length;
      }
  
      public void assembleProfiles() throws Exception
      {
          Iterator iterator = m_assembly.iterator();
          while( iterator.hasNext() )
          {
              Profile profile = (Profile) iterator.next();
              getLogger().debug("assembly target: " + profile );
              ArrayList visited = new ArrayList();
              assemble( profile, visited, "" );
              m_map.add( profile );
              m_installed.add( profile );
          }
      }
  
      private void assemble( Profile profile, List visited, String pad ) throws Exception
      {
          getLogger().debug( pad + "assemble: " + profile );
          String pad2 = pad + "  ";
          visited.add( profile );
          DependencyDescriptor[] dependencies = profile.getType().getDependencies();
          for( int i=0; i<dependencies.length; i++ )
          {
              DependencyDescriptor dependency = dependencies[i];
              String role = dependency.getRole();
              if( profile.getAssociation( role ) == null )
              {
                  Profile[] candidates = assemble( profile, dependency, visited, pad2 );
                  Profile[] facilities = getFacilities( dependency.getService() );
                  Profile provider = selectProfile( dependency, facilities, candidates );
                  if( provider == null )
                  {
                      throw new UnresolvedProviderException("no available provider", dependency );
                  }
                  else
                  {
                      profile.addProvider( provider, role );
                      if( isLocalProfile( provider ) ) 
                      {
                          m_map.add( provider );
                          m_installed.add( provider );
                      }
                  }
              }
          }
      }
  
      public boolean isLocalProfile( Profile profile )
      {
          return m_profiles.values().contains( profile );
      }
  
      private Profile[] assemble( Profile source, DependencyDescriptor dependency, List visited, String pad )
         throws Exception
      {
          getLogger().debug( pad + "dependency: " + dependency.getRole() );
          Vector vector = new Vector();
          String pad2 = pad + "  ";
          Profile[] profiles = getProfiles( dependency.getService() );
          for( int i=0; i<profiles.length; i++ )
          {
              Profile provider = profiles[i];
              if( !provider.equals( source ) )
              {
                  try
                  {
                      assemble( provider, visited, pad2 );
                      vector.add( provider );
                      getLogger().debug( pad + "candidate: " + provider );
                  }
                  catch( Throwable e )
                  {
                      // solution is not resolvable
                  }
              }
          }
          return (Profile[]) vector.toArray( new Profile[0] );
      }
      
      private void prepareDirectives() throws Exception
      {
          for( int i=0; i<m_directives.length; i++ )
          {
              Profile profile = register( m_directives[i] );
              m_assembly.add( profile );
          }
      }
  
      private void prepareTypes() throws Exception
      {
          Type[] types = m_types.getTypes();
          for( int i=0; i<types.length; i++ )
          {
              register( types[i] );
          }
      }
  
      private Profile register( Configuration directive ) throws Exception
      {
          Type type = m_types.getType( directive.getAttribute("class") );
          Profile profile = m_builder.build( type, directive );
          return register( profile );
      }
      
     /**
      * 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 Profile[] register( Type type ) throws Exception
      {
          Profile[] profiles = m_builder.build( type, m_classloader );
          for( int i=0; i<profiles.length; i++ )
          {
              Profile profile = profiles[i];
              register( profile );
          }
          return profiles;
      }
  
     /**
      * Returns the set of component types know to the registry.
      * @return the set of component types registered with the registry
      */
      public Profile[] getProfiles()
      {
          return (Profile[]) m_profiles.values().toArray( new Profile[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 Profile[] getProfiles( ServiceDesignator service )
      {
          return getTable( service ).getProfiles();
      }
  
     /**
      * Returns a registered component type.
      * @return the component type from the registry or null if the type is unknown
      * @exception IllegalArgumentException if the classname does not correpond to a know component
      */
      public Profile getProfile( String name ) throws IllegalArgumentException
      {
          return (Profile) m_profiles.get( name );
      }
  
     /**
      * 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 Profile register( Profile profile )
      {
          String name = profile.getName();
          m_profiles.put( name, profile );
          getLogger().debug( "" + profile );
          ServiceDescriptor[] services = profile.getType().getServices();
          for( int i=0; i<services.length; i++ )
          {
              register( services[i].getServiceDesignator(), profile );
          }
          return profile;
      }
  
     /**
      * Register a type under a service cross-reference.
      */
      private void register( ServiceDesignator service, Profile profile )
      {
          ProfileTable table = getTable( service );
          table.add( profile );
      }
  
     /**
      * Return a table holding table capable of supply the supplied service.
      */
      private ProfileTable getTable( ServiceDesignator service )
      {
          ProfileTable table = null;
          Iterator iterator = m_services.iterator();
          while( iterator.hasNext() )
          {
              table = (ProfileTable) iterator.next();
              if( table.matches( service ) )
                return table;
          }
  
          // otherwise create a new table
          table = new ProfileTable( service, getLogger().getChildLogger("table")  );
          m_services.add( table );
          return table;
      }
  
      private Selector getSelector( DependencyDescriptor dependency )
      {
  
          // if the dependency declares a selector class then use that, 
          // otherwise, look for a default service type selector
  
          String selectorName = dependency.getAttribute("avalon.service.selector");
          if( selectorName == null )
            selectorName = dependency.getService().getClassname() + "Selector";
          try
          {
              Class clazz = m_classloader.loadClass( selectorName );
              Selector selector = (Selector) clazz.newInstance();
              if( selector instanceof LogEnabled ) 
              {
                  ((LogEnabled)selector).enableLogging( getLogger().getChildLogger("selector") );
              }
              return selector;
          }
          catch( Throwable e )
          {
              return null;
          }
      }
  
      private Profile[] getFacilities( ServiceDesignator service )
      {
          if( m_parent != null )
          {
              return m_parent.getProviders( service );
          }
          else
          {
              return new Profile[0];
          }
      }
  
      private Profile selectProfile( DependencyDescriptor dependency, Profile[] facilities, Profile[] profiles )
      {
          Selector selector = getSelector( dependency );
          if( selector != null )
          {
              return selector.select( facilities, profiles );
          }
          else
          {
              // apply default selection policy
              Profile profile = select( profiles, Profile.EXPLICIT );
              if( profile == null )
              {
                  profile = select( facilities );
              }
              if( profile == null )
              {
                  profile = select( profiles );
              }
              return profile;
          }
      }
  
      private Profile select( Profile[] profiles )
      {
          Profile profile = select( profiles, Profile.EXPLICIT );
          if( profile == null ) profile = select( profiles, Profile.PACKAGED );
          if( profile == null ) profile = select( profiles, Profile.IMPLICIT );
          return profile;
      }
  
      private Profile select( Profile[] profiles, int mode )
      {
          for( int i=0; i<profiles.length; i++ )
          {
              if( profiles[i].getMode() == mode )
                return profiles[i];
          }
          return null;
      }
  
  
  }
  
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/ProfileTable.java
  
  Index: ProfileTable.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.registry;
  
  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;
  import org.apache.excalibur.meta.data.Profile;
  
  /**
   * Internal table that holds references to the available component types 
   * that represent candidate providers for a single service type. 
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/07 04:40:15 $
   */
  final class ProfileTable 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 ProfileTable( 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( Profile profile )
      {
          m_providers.add( profile );
      }
  
     /**
      * 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 Profile[] getProfiles()
      {
          return (Profile[]) m_providers.toArray( new Profile[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 "ProfileTable:" 
           + System.identityHashCode( this ) 
           + ", " 
           + m_designator;
      }
  }
  
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/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.registry;
  
  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.data.Profile;
  import org.apache.excalibur.meta.verifier.ComponentVerifier;
  import org.apache.excalibur.meta.builder.TypeBuilder;
  import org.apache.excalibur.configuration.ConfigurationUtil;
  import org.apache.excalibur.merlin.kernel.Map;
  
  /**
   * Internal table that holds available component type keyed relative
   * to the service it provides.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/07 04:40:15 $
   */
  final class TypeRegistry extends AbstractLogEnabled
  {
  
      //=======================================================================
      // state
      //=======================================================================
  
      private TypeBuilder m_infoBuilder = new TypeBuilder();
      private ClassLoader m_classloader;
      private DefaultRegistry m_registry;
  
     /**
      * 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( 
        DefaultRegistry registry, ClassLoader loader )
      {
          m_classloader = loader;
          m_registry = registry;
      }
  
      //=======================================================================
      // 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") );
      }
  
      //=======================================================================
      // ServiceRegistry
      //=======================================================================
  
     /**
      * 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;
      }
  
      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
      */
      Class getComponentClass( Type type ) throws RegistryException
      {
          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 RegistryException( error, e );
          }
      }
  
  
     /**
      * Returns the service type implementation class.
      * @param service the service type descriptor
      * @return the class implementing the service type
      */
      Class getServiceClass( ServiceDescriptor service ) throws RegistryRuntimeException
      {
          final String classname = service.getServiceDesignator().getClassname();
          try
          {
              return m_classloader.loadClass( classname );
          }
          catch( Throwable e )
          {
              final String error = "Could not load implementation class for service type: "
                + classname;
              throw new RegistryRuntimeException( 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
      * @exception IllegalArgumentException if the classname does not correpond to a know component
      */
      public Type getType( String classname ) throws IllegalArgumentException
      {
          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].getServiceDesignator(), 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;
      }
  }
  
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/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.registry;
  
  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:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/07 04:40:15 $
   */
  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 )
      {
          //getLogger().debug("addition\n\ttype:" + type + "\n\ttable: " + this );
          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;
      }
  }
  
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>