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 2003/07/22 06:11:58 UTC

cvs commit: avalon-sandbox/merlin/merlin-extensions/merlin-jndi/src/java/org/apache/avalon/merlin/jndi ServiceFactory.java

mcconnell    2003/07/21 21:11:58

  Modified:    merlin   maven.xml
               merlin/composition/src/java/org/apache/avalon/composition/model/impl
                        DefaultClassLoaderModel.java
                        DefaultDependencyModel.java Resources.properties
               merlin/composition/src/test/org/apache/avalon/composition/model/test
                        DependencyTestCase.java
               merlin/composition-spi/src/java/org/apache/avalon/composition/data
                        DependencyDirective.java
               merlin/composition-spi/src/java/org/apache/avalon/composition/model
                        DependencyModel.java
               merlin/merlin-extensions/merlin-jndi/src/java/org/apache/avalon/merlin/jndi
                        ServiceFactory.java
  Log:
  Fixed a couple of exception throws that wer using 1.4 constructors and updated the composition package to handle service filtering.
  
  Revision  Changes    Path
  1.28      +0 -2      avalon-sandbox/merlin/maven.xml
  
  Index: maven.xml
  ===================================================================
  RCS file: /home/cvs/avalon-sandbox/merlin/maven.xml,v
  retrieving revision 1.27
  retrieving revision 1.28
  diff -u -r1.27 -r1.28
  --- maven.xml	14 Jul 2003 22:07:27 -0000	1.27
  +++ maven.xml	22 Jul 2003 04:11:56 -0000	1.28
  @@ -232,8 +232,6 @@
           <j:forEach var="packageGroup" items="${pom.packageGroups}">
         	  <group title="${packageGroup.title}" packages="${packageGroup.packages}"/>
           </j:forEach>
  -        <sourcepath path="${basedir}/../meta-spi/src/java"/>
  -        <sourcepath path="${basedir}/../meta/src/java"/>
           <sourcepath path="${basedir}/../extension-spi/src/java"/>
           <sourcepath path="${basedir}/../extension/src/java"/>
           <!--
  
  
  
  1.13      +3 -3      avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/DefaultClassLoaderModel.java
  
  Index: DefaultClassLoaderModel.java
  ===================================================================
  RCS file: /home/cvs/avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/DefaultClassLoaderModel.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- DefaultClassLoaderModel.java	17 Jul 2003 21:21:57 -0000	1.12
  +++ DefaultClassLoaderModel.java	22 Jul 2003 04:11:57 -0000	1.13
  @@ -549,7 +549,7 @@
       }
   
       private Manifest[] getManifests( final String[] classPath )
  -            throws Exception
  +            throws ModelException
       {
           final ArrayList manifests = new ArrayList();
           for( int i = 0; i < classPath.length; i++ )
  @@ -579,7 +579,7 @@
                   {
                       final String message =
                         REZ.getString( "classloader.bad-classpath-entry.error", element );
  -                    throw new Exception( message, ioe );
  +                    throw new ModelException( message, ioe );
                   }
               }
           }
  
  
  
  1.3       +315 -16   avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/DefaultDependencyModel.java
  
  Index: DefaultDependencyModel.java
  ===================================================================
  RCS file: /home/cvs/avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/DefaultDependencyModel.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- DefaultDependencyModel.java	19 Jul 2003 06:16:42 -0000	1.2
  +++ DefaultDependencyModel.java	22 Jul 2003 04:11:57 -0000	1.3
  @@ -62,11 +62,13 @@
   import org.apache.avalon.composition.model.Model;
   import org.apache.avalon.composition.model.ModelException;
   import org.apache.avalon.composition.data.DependencyDirective;
  +import org.apache.avalon.composition.data.SelectionDirective;
   import org.apache.avalon.excalibur.i18n.ResourceManager;
   import org.apache.avalon.excalibur.i18n.Resources;
   import org.apache.avalon.framework.logger.AbstractLogEnabled;
   import org.apache.avalon.framework.logger.Logger;
   import org.apache.avalon.meta.info.DependencyDescriptor;
  +import org.apache.avalon.meta.info.ServiceDescriptor;
   
   /**
    * Default implementation of the deplendency model.
  @@ -95,6 +97,8 @@
   
       private final String m_name;
   
  +    private final Map m_paths = new Hashtable();
  +
       //==============================================================
       // mutable state
       //==============================================================
  @@ -125,6 +129,26 @@
           m_partition = partition;
           m_name = name;
   
  +        //
  +        // a dependency directive is either declaring an explicitly
  +        // identified provider, or, it is delcaring 0 or more selection 
  +        // constraints - if its a an absolute source declaration then 
  +        // add it to the table to paths keyed by depedency key names
  +        //
  +
  +        for( int i=0; i<directives.length; i++ )
  +        {
  +            DependencyDirective directive = directives[i];
  +            if( directive.getSource() != null )
  +            {
  +                String source = resolvePath( m_partition, directive.getSource() );
  +                m_paths.put( directive.getKey(), source );
  +
  +                final String message =
  +                  REZ.getString( "dependency.path.debug", source, directive.getKey() );
  +                getLogger().debug( message );
  +            }
  +        }
       }
   
       //==============================================================
  @@ -132,10 +156,31 @@
       //==============================================================
   
      /**
  +    * Return an explicit path to a component relative to a supplied 
  +    * dependency key.  If a dependency directive has been declared
  +    * and the directive contains a source declaration, the value 
  +    * returned is the result of parsing the source value relative 
  +    * to the absolute address of the implementing component.
  +    *
  +    * @return the explicit path
  +    * @exception IllegalArgumentException if the key is unknown
  +    */
  +    public String getPath( String key ) throws IllegalArgumentException
  +    {
  +        if( !valideKey( key ) )
  +        {
  +            final String error = 
  +              REZ.getString( "dependency.bad-key.error", key, m_partition, m_name );
  +            throw new IllegalArgumentException( error );
  +        }
  +        return (String) m_paths.get( key );
  +    }
  +
  +   /**
       * Return the set of dependecies for the model.
       *
       * @return the the set of descriptors declaring the component 
  -    *    depedencies
  +    *    dependencies
       */
       public DependencyDescriptor[] getDependencies()
       {
  @@ -151,35 +196,251 @@
       * @param candidates the set of candidate models
       * @return the selected candidate 
       */
  -    public Model select( String key, Model[] candidates )
  +    public Model select( String key, Model[] candidates ) throws ModelException
       {
           DependencyDirective directive = getDirective( key );
           if( directive != null )
           {
  -            if( directive != null )
  +            if( directive.getSource() != null )
               {
  -                if( directive.getSource() != null )
  +                //
  +                // its an explicit assignment
  +                //
  +
  +                String path = directive.getSource();
  +                String source = resolvePath( m_partition, path );
  +                for( int i=0; i<candidates.length; i++ )
                   {
  -                    String path = directive.getSource();
  -                    String source = resolvePath( m_partition, path );
  -                    for( int i=0; i<candidates.length; i++ )
  +                    final Model candidate = candidates[i];
  +                    final String name = candidate.getQualifiedName();
  +                    if( source.equals( name ) )
                       {
  -                        final Model candidate = candidates[i];
  -                        final String name = candidate.getQualifiedName();
  -                        if( source.equals( name ) )
  -                        {
  -                            getLogger().debug( 
  -                              "selected [" + name + "] for key [" 
  -                              + key + "] using [" + path + "].");
  -                            return candidate;
  -                        }
  +                        getLogger().debug( 
  +                          "selected [" + name + "] for key [" 
  +                          + key + "] using [" + path + "].");
  +                        return candidate;
                       }
                   }
  +                    
  +                //
  +                // and if we get here it means that the explicit 
  +                // directive did not lead to a resolvable solution
  +                // so we need to get nasty and throw an exception
  +                //
  +
  +                final String error = 
  +                  REZ.getString( 
  +                    "dependency.unresolvable-directive.error",
  +                    key, m_partition, m_name, path );
  +                throw new ModelException( error );
               }
           }
           return null;
       }
   
  +   /**
  +    * Filter a set of candidate service descriptors and return the 
  +    * set of acceptable service as a ordered sequence.
  +    *
  +    * @param key the dependency key
  +    * @param candidates the set of candidate services for the dependency
  +    *    matching the supplied key
  +    * @return the accepted candidates in ranked order
  +    * @exception IllegalArgumentException if the key is unknown
  +    */
  +    public ServiceDescriptor[] filter( String key, ServiceDescriptor[] candidates ) 
  +    {
  +        if( !valideKey( key ) )
  +        {
  +            final String error = 
  +              REZ.getString( "dependency.bad-key.error", key, m_partition, m_name );
  +            throw new IllegalArgumentException( error );
  +        }
  +
  +        DependencyDirective directive = getDirective( key );
  +        if( directive != null )
  +        {
  +            if( directive.getSource() == null )
  +            {
  +                return filter( directive, candidates );
  +            }
  +        }
  +        return candidates;
  +    }
  +
  +   /**
  +    * Filter a set of candidate service descriptors and return the 
  +    * set of acceptable service as a ordered sequence.
  +    *
  +    * @param key the dependency directive
  +    * @param candidates the set of candidate services for the dependency
  +    * @return the accepted candidates in ranked order
  +    */
  +    private ServiceDescriptor[] filter( 
  +      DependencyDirective directive, ServiceDescriptor[] services ) 
  +    {
  +        SelectionDirective[] filters = getFilters( directive );
  +        ArrayList list = new ArrayList();
  +
  +        for( int i=0; i<services.length; i++ )
  +        {
  +            ServiceDescriptor service = services[i];
  +            if( isaCandidate( service, filters ) )
  +            {
  +                list.add( service );
  +            }
  +        }
  +
  +        ServiceDescriptor[] candidates = 
  +          (ServiceDescriptor[]) list.toArray( new ServiceDescriptor[0] );
  +
  +        //
  +        // TODO: include ranking of candidates
  +        //
  +
  +        return candidates;
  +    }
  +
  +    private boolean isaCandidate( 
  +      ServiceDescriptor service, SelectionDirective[] filters )
  +    {
  +        for( int i=0; i<filters.length; i++ )
  +        {
  +            SelectionDirective filter = filters[i];
  +            if( !isaCandidate( service, filter ) )
  +            {
  +                return false;
  +            }
  +        }
  +        return true;
  +    }
  +
  +    private boolean isaCandidate( 
  +      ServiceDescriptor service, SelectionDirective filter )
  +    {
  +        final String feature = filter.getFeature();
  +        final String value = filter.getValue();
  +        final String criteria = filter.getCriteria();
  +
  +        if( criteria.equals( SelectionDirective.EQUALS ) )
  +        {
  +            return value.equals( service.getAttribute( feature ) );
  +        }
  +        else if( criteria.equals( SelectionDirective.EXISTS ) )
  +        {
  +            return service.getAttribute( feature ) != null;
  +        }
  +        else if( criteria.equals( SelectionDirective.INCLUDES ) )
  +        {
  +            final String v = service.getAttribute( feature );
  +            if( v != null )
  +            {
  +                return v.indexOf( value ) > -1;
  +            }
  +            else
  +            {
  +                return false;
  +            }
  +        }
  +        else
  +        {
  +            final String error = 
  +              REZ.getString( "dependency.invalid-criteria.error", criteria, feature );
  +            throw new IllegalArgumentException( error );
  +        }
  +    }
  +
  +
  +   /**
  +    * Rank a service relative to the service it provides matching
  +    * the dependency key.
  +    *
  +    * @param directive the dependency directive
  +    * @param candidate a candidate model
  +    */
  +/*
  +    private int rank( DependencyDirective directive, ServiceDescriptor service )
  +    {
  +        int n = 0;
  +        SelectionDirective[] selections = 
  +          directive.getSelectionDirectives();
  +        for( int i=0; i<selections.length; i++ )
  +        {
  +            int ranking = rank( service, selections[i] );
  +            if( ranking > -1 )
  +            {
  +                n = n + ranking;
  +            }
  +            else
  +            {
  +                return -1;
  +            }
  +        }
  +        return n;
  +    }
  +
  +    private int rank( ServiceDescriptor service, SelectionDirective directive )
  +    {
  +        String feature = directive.getFeature();
  +        String value = directive.getValue();
  +        if( directive.getCriteria().equals( SelectionDirective.EQUALS ) )
  +        {
  +            if( value.equals( service.getAttribute( feature ) )
  +            {
  +                return 1;
  +            }
  +            else
  +            {
  +                if( directive.isRequired() )
  +                {
  +                    return -1;
  +                }
  +                else
  +                {
  +                    return 0;
  +                }
  +            }
  +        }
  +        else if( directive.getCriteria().equals( SelectionDirective.INCLUDES ) )
  +        {
  +            final String v = service.getAttribute( feature );
  +            if( v != null )
  +            {
  +                if( v.indexOf( value ) > -1 )
  +                {
  +                    return 1;
  +                }
  +            }
  +            if( directive.isRequired() )
  +            {
  +                return -1;
  +            }
  +            else
  +            {
  +                return 0;
  +            }
  +        }
  +        else if( directive.getCriteria().equals( SelectionDirective.EXISTS ) )
  +        {
  +            if( service.getAttribute( feature ) != null )
  +            {
  +                return 1;
  +            }
  +            else
  +            {
  +                if( directive.isRequired() )
  +                {
  +                    return -1;
  +                }
  +                else
  +                {
  +                    return 0;
  +                }
  +            }
  +        }
  +    }
  +*/
  +
       private String resolvePath( String partition, String path )
       {
           if( path.startsWith( "/" ) )
  @@ -232,5 +493,43 @@
               if( directive.getKey().equals( key ) ) return directive;
           }
           return null;
  +    }
  +
  +   /**
  +    * Validate that a key is known withing the set of 
  +    * dependency descriptors.
  +    * @param key the key to validate
  +    * @return TRUE if the key is known
  +    */
  +    private boolean valideKey( final String key )
  +    {
  +        for( int i=0; i<m_descriptors.length; i++ )
  +        {
  +            if( m_descriptors[i].getKey().equals( key ) )
  +            {
  +                return true;
  +            }
  +        }
  +        return false;
  +    }
  +
  +   /**
  +    * Return the required selection constraints.
  +    * @param directive the dependency directive
  +    * @return the set of required selection directives
  +    */
  +    private SelectionDirective[] getFilters( DependencyDirective directive )
  +    {
  +        ArrayList list = new ArrayList();
  +        SelectionDirective[] selections = directive.getSelectionDirectives();
  +        for( int i=0; i<selections.length; i++ )
  +        {
  +            SelectionDirective selection = selections[i];
  +            if( selection.isRequired() )
  +            {
  +                list.add( selection );
  +            }
  +        }
  +        return (SelectionDirective[]) list.toArray( new SelectionDirective[0] );
       }
   }
  
  
  
  1.13      +7 -0      avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/Resources.properties
  
  Index: Resources.properties
  ===================================================================
  RCS file: /home/cvs/avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/Resources.properties,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- Resources.properties	19 Jul 2003 06:16:42 -0000	1.12
  +++ Resources.properties	22 Jul 2003 04:11:57 -0000	1.13
  @@ -105,3 +105,10 @@
   constructor.directive.load.error=The constructor entry directive declared under the key [{0}] references a class [{1}] that that could not be loaded due to an runtime error. 
   constructor.invalid-model.error=The component type declares a dependency under the context entry [{0}] on a runtime entry of the type [{1}], however, the corresponding directive declares a constructor that establishes an instance of the class [{2}] which does not implement or extend the class declared by the directive.
   
  +# DefaultDependencyModel
  +# ======================
  +dependency.unresolvable-directive.error=Unable to resolve a candidate deployment model for the dependency key [{0}] in the deployment model [{1}{2}] relative to the declared source directive [{3}].
  +dependency.bad-key.error=The supplied key [{0}] is unknown within the model [{1}{2}].
  +dependency.incompatible.error=Cannot process a selection for key [{0}] because an source directive has been declared.
  +dependency.invalid-criteria.error=Unknown criteria: [{0}] declared under the selection criteria referencing the feature: [{1}].
  +dependency.path.debug=Assigned source [{0}] for the dependency key [{1}].
  \ No newline at end of file
  
  
  
  1.3       +2 -12     avalon-sandbox/merlin/composition/src/test/org/apache/avalon/composition/model/test/DependencyTestCase.java
  
  Index: DependencyTestCase.java
  ===================================================================
  RCS file: /home/cvs/avalon-sandbox/merlin/composition/src/test/org/apache/avalon/composition/model/test/DependencyTestCase.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- DependencyTestCase.java	19 Jul 2003 06:16:42 -0000	1.2
  +++ DependencyTestCase.java	22 Jul 2003 04:11:57 -0000	1.3
  @@ -61,20 +61,10 @@
               fail( "null dependency descriptor array" );
           }
   
  -        Model[] candidates = new Model[]{ a, b };
           for( int i=0; i<deps.length; i++ )
           {
               String key = deps[i].getKey();
  -            try
  -            {
  -                Model selection = dependencyModel.select( key, candidates );
  -                assertNotNull( "selection for key: " + key, selection );
  -            }
  -            catch( Throwable e )
  -            {
  -                e.printStackTrace();
  -                fail( "resolving explicit dependency directive failed for key: " + key );
  -            }
  +            assertNotNull( "selection for key: " + key, dependencyModel.getPath( key ) );
           }
  -    }
  +    } 
   }
  
  
  
  1.2       +1 -2      avalon-sandbox/merlin/composition-spi/src/java/org/apache/avalon/composition/data/DependencyDirective.java
  
  Index: DependencyDirective.java
  ===================================================================
  RCS file: /home/cvs/avalon-sandbox/merlin/composition-spi/src/java/org/apache/avalon/composition/data/DependencyDirective.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- DependencyDirective.java	17 Jul 2003 21:21:58 -0000	1.1
  +++ DependencyDirective.java	22 Jul 2003 04:11:57 -0000	1.2
  @@ -129,5 +129,4 @@
       {
           return m_features;
       }
  -
   }
  
  
  
  1.2       +25 -13    avalon-sandbox/merlin/composition-spi/src/java/org/apache/avalon/composition/model/DependencyModel.java
  
  Index: DependencyModel.java
  ===================================================================
  RCS file: /home/cvs/avalon-sandbox/merlin/composition-spi/src/java/org/apache/avalon/composition/model/DependencyModel.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- DependencyModel.java	19 Jul 2003 05:25:35 -0000	1.1
  +++ DependencyModel.java	22 Jul 2003 04:11:57 -0000	1.2
  @@ -51,6 +51,7 @@
   package org.apache.avalon.composition.model;
   
   import org.apache.avalon.meta.info.DependencyDescriptor;
  +import org.apache.avalon.meta.info.ServiceDescriptor;
   
   /**
    * Dependency model defintion.
  @@ -60,24 +61,35 @@
    */
   public interface DependencyModel
   {
  -
      /**
       * Return the set of dependecies for the model.
       *
       * @return the the set of descriptors declaring the component 
  -    *    depedencies
  +    *    dependencies
       */
       DependencyDescriptor[] getDependencies();
   
  -    /**
  -     * Select a model for a set of candidates taking into account the 
  -     * the depedency directives and dependency descriptors associated 
  -     * with the component type that this model is representing.
  -     *
  -     * @param key the dependency key
  -     * @param candidates the set of candidate models
  -     * @return the selected candidate 
  -     */
  -     Model select( String key, Model[] candidates );
  +   /**
  +    * Return an explicit path to a component relative to a supplied 
  +    * dependency key.  If a dependency directive has been declared
  +    * and the directive contains a source declaration, the value 
  +    * returned is the result of parsing the source value relative 
  +    * to the absolute address of the implementing component.
  +    *
  +    * @return the explicit path
  +    * @exception IllegalArgumentException if the key is unknown
  +    */
  +    String getPath( String key ) throws IllegalArgumentException;
  +
  +   /**
  +    * Filter a set of candidate service descriptors and return the 
  +    * set of acceptable service as a andered sequence.
  +    *
  +    * @param key the dependency key
  +    * @param candidates the set of candidate services for the dependency
  +    *    matching the supplied key
  +    * @return the accepted candidates in ranked order
  +    */
  +    ServiceDescriptor[] filter( String key, ServiceDescriptor[] candidates );
   
   }
  
  
  
  1.5       +9 -38     avalon-sandbox/merlin/merlin-extensions/merlin-jndi/src/java/org/apache/avalon/merlin/jndi/ServiceFactory.java
  
  Index: ServiceFactory.java
  ===================================================================
  RCS file: /home/cvs/avalon-sandbox/merlin/merlin-extensions/merlin-jndi/src/java/org/apache/avalon/merlin/jndi/ServiceFactory.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- ServiceFactory.java	12 Jun 2003 18:56:20 -0000	1.4
  +++ ServiceFactory.java	22 Jul 2003 04:11:57 -0000	1.5
  @@ -174,58 +174,29 @@
           }
       }
   
  -    private Object loadKernel( ClassLoader loader, Map map )
  +    private Object loadKernel( ClassLoader loader, Map map ) throws Exception
       {
           Thread.currentThread().setContextClassLoader( loader );
           Object kernelLoader = null;
  -        Class clazz;
  +        
   
           //
           // load the kernel loader class from the supplied classloader
  +        // and instantiate the loader
           //
   
  -        try
  -        {
  -            clazz = loader.loadClass( MERLIN_KERNEL_LOADER_CLASSNAME );
  -        }
  -        catch( Throwable e )
  -        {
  -            final String error =
  -              "Internal error during loader class creation.";
  -            throw new RuntimeException( error, e );
  -        }
  +        Class clazz = loader.loadClass( MERLIN_KERNEL_LOADER_CLASSNAME );
   
  -        //
  -        // instantiate the loader
  -        //
  -
  -        try
  -        {
  -            Constructor constructor = clazz.getConstructor( new Class[0] );
  -            kernelLoader = constructor.newInstance( new Object[0] );
  -        }
  -        catch( Throwable e )
  -        {
  -            final String error =
  -              "Internal error during loader instantiation.";
  -            throw new RuntimeException( error, e );
  -        }
  +        Constructor constructor = clazz.getConstructor( new Class[0] );
  +        kernelLoader = constructor.newInstance( new Object[0] );
   
           //
           // create the kernel instance
           //
   
  -        try
  -        {
  -            Method method = kernelLoader.getClass().getMethod( "build", new Class[]{ Map.class } );
  -            return method.invoke( kernelLoader, new Object[]{ map } );
  -        }
  -        catch( Throwable e )
  -        {
  -            final String error =
  -              "Internal error during kernel resolution.";
  -            throw new RuntimeException( error, e );
  -        }
  +        Method method = 
  +          kernelLoader.getClass().getMethod( "build", new Class[]{ Map.class } );
  +        return method.invoke( kernelLoader, new Object[]{ map } );
       }
   
       private static URL[] getJarFiles( File base )
  
  
  

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