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/25 00:14:55 UTC

cvs commit: avalon-sandbox/merlin/composition/src/test/org/apache/avalon/composition/data/test DeploymentProfileTestCase.java

mcconnell    2003/07/24 15:14:55

  Modified:    merlin/composition/src/java/org/apache/avalon/composition/data/builder
                        XMLDeploymentProfileCreator.java
               merlin/composition/src/java/org/apache/avalon/composition/data/writer
                        XMLDeploymentProfileWriter.java
               merlin/composition/src/java/org/apache/avalon/composition/model/impl
                        DefaultDeploymentModel.java
               merlin/composition/src/test/org/apache/avalon/composition/data/test
                        DeploymentProfileTestCase.java
  Added:       merlin/composition/src/java/org/apache/avalon/composition/model/impl
                        DefaultStageModel.java
  Log:
  Implementation of a stage model that provides suppport for the explicit declaration of a stage provider (via component address) or via extension selection constrain filtering.
  
  Revision  Changes    Path
  1.2       +48 -5     avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/data/builder/XMLDeploymentProfileCreator.java
  
  Index: XMLDeploymentProfileCreator.java
  ===================================================================
  RCS file: /home/cvs/avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/data/builder/XMLDeploymentProfileCreator.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XMLDeploymentProfileCreator.java	17 Jul 2003 21:21:56 -0000	1.1
  +++ XMLDeploymentProfileCreator.java	24 Jul 2003 22:14:55 -0000	1.2
  @@ -111,14 +111,16 @@
             getContextDirective( config.getChild( "context", false ) );
           final DependencyDirective[] dependencies = 
             getDependencyDirectives( config.getChild( "dependencies" ) );
  +        final StageDirective[] stages = 
  +          getStageDirectives( config.getChild( "stages" ) );
           final Parameters params = 
             getParameters( config.getChild( "parameters", false ) );
           final Configuration configuration = 
             config.getChild( "configuration", false );
   
           return new DeploymentProfile( 
  -          name, activation, classname, categories, context, dependencies, params, 
  -          configuration, Mode.EXPLICIT );
  +          name, activation, classname, categories, context, dependencies, 
  +          stages, params, configuration, Mode.EXPLICIT );
       }
   
       protected DependencyDirective[] getDependencyDirectives( Configuration config )
  @@ -160,6 +162,45 @@
           }
       }
   
  +    protected StageDirective[] getStageDirectives( Configuration config )
  +      throws ConfigurationException
  +    {
  +        if( config != null )
  +        {
  +            ArrayList list = new ArrayList();
  +            Configuration[] deps = config.getChildren( "stage" );
  +            for( int i=0; i<deps.length; i++ )
  +            {
  +                list.add( getStageDirective( deps[i] ) );
  +            }
  +            return (StageDirective[]) list.toArray( new StageDirective[0] );
  +        }
  +        return new StageDirective[0];
  +    }
  +
  +    protected StageDirective getStageDirective( Configuration config )
  +      throws ConfigurationException
  +    {
  +        final String key = config.getAttribute( "key" );
  +        final String source = config.getAttribute( "source", null );
  +        if( source != null )
  +        {
  +            return new StageDirective( key, source );
  +        }
  +        else
  +        {
  +            Configuration[] children = config.getChildren( "select" );
  +            ArrayList list = new ArrayList();
  +            for( int i=0; i<children.length; i++ )
  +            {
  +                list.add( getSelectionDirective( children[i] ) );
  +            }
  +            SelectionDirective[] features = 
  +              (SelectionDirective[]) list.toArray( new SelectionDirective[0] );
  +            return new StageDirective( key, features );
  +        }
  +    }
  +
       protected SelectionDirective getSelectionDirective( Configuration config )
         throws ConfigurationException
       {
  @@ -170,14 +211,16 @@
           return new SelectionDirective( feature, value, match, optional );
       }
   
  -    protected CategoriesDirective getCategoriesDirective( Configuration config, String name )
  +    protected CategoriesDirective getCategoriesDirective( 
  +      Configuration config, String name )
         throws ConfigurationException
       {
           if( config != null )
           {
               String priority = config.getAttribute( "priority", null );
               String target = target = config.getAttribute( "target", null );
  -            CategoryDirective[] categories = getCategoryDirectives( config.getChildren( "category" ) );
  +            CategoryDirective[] categories = 
  +              getCategoryDirectives( config.getChildren( "category" ) );
               return new CategoriesDirective( name, priority, target, categories );
           }
           return null;
  
  
  
  1.2       +54 -2     avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/data/writer/XMLDeploymentProfileWriter.java
  
  Index: XMLDeploymentProfileWriter.java
  ===================================================================
  RCS file: /home/cvs/avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/data/writer/XMLDeploymentProfileWriter.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XMLDeploymentProfileWriter.java	17 Jul 2003 21:21:57 -0000	1.1
  +++ XMLDeploymentProfileWriter.java	24 Jul 2003 22:14:55 -0000	1.2
  @@ -68,6 +68,7 @@
   import org.apache.avalon.composition.data.ImportDirective;
   import org.apache.avalon.composition.data.EntryDirective;
   import org.apache.avalon.composition.data.ConstructorDirective;
  +import org.apache.avalon.composition.data.StageDirective;
   import org.apache.avalon.composition.data.Parameter;
   import org.apache.excalibur.configuration.ConfigurationUtil;
   
  @@ -132,6 +133,7 @@
           writeCategories( writer, profile.getCategories(), pad );
           writeContext( writer, profile.getContext(), pad );
           writeDependencies( writer, profile.getDependencyDirectives(), pad );
  +        writeStages( writer, profile.getStageDirectives(), pad );
           writeConfiguration( writer, profile.getConfiguration(), pad );
           writeParameters( writer, profile.getParameters(), pad );
       }
  @@ -187,7 +189,57 @@
       }
   
       /**
  -     * Write out xml representation of a dependency selection directive.
  +     * Write out xml representation of the dependency directives.
  +     *
  +     * @param writer the writer
  +     * @param dependencies the dependency directives
  +     * @throws IOException if unable to write xml
  +     */
  +    private void writeStages( 
  +      final Writer writer, final StageDirective[] stages, String pad )
  +      throws IOException
  +    {
  +        if( stages.length == 0 ) return;
  +        writer.write( "\n" + pad + "<stages>" );
  +        final String padding = pad + INDENT;
  +        for( int i=0; i<stages.length; i++ )
  +        {
  +            writeStage( writer, stages[i], padding );
  +        }
  +        writer.write( "\n" + pad + "</stages>" );
  +    }
  +
  +    /**
  +     * Write out xml representation of a stage directive.
  +     *
  +     * @param writer the writer
  +     * @param stage the stage directive
  +     * @throws IOException if unable to write xml
  +     */
  +    private void writeStage( 
  +      final Writer writer, final StageDirective stage, String pad )
  +      throws IOException
  +    {
  +        writer.write( "\n" + pad + "<stage key=\"" + stage.getKey() + "\"" );
  +        if( stage.getSource() != null )
  +        {
  +            writer.write( " source=\"" + stage.getSource() + "\"/>" );
  +        }
  +        else
  +        {
  +            writer.write( ">" );
  +            SelectionDirective[] features = stage.getSelectionDirectives();
  +            final String padding = pad + INDENT;
  +            for( int i=0; i<features.length; i++ )
  +            {
  +                writeSelectionDirective( writer, features[i], padding );
  +            }
  +            writer.write( "\n" + pad + "</stage>" );
  +        }
  +    }
  +
  +    /**
  +     * Write out xml representation of a selection directive.
        *
        * @param writer the writer
        * @param feature the dependency selection directive
  
  
  
  1.17      +39 -3     avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/DefaultDeploymentModel.java
  
  Index: DefaultDeploymentModel.java
  ===================================================================
  RCS file: /home/cvs/avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/DefaultDeploymentModel.java,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- DefaultDeploymentModel.java	24 Jul 2003 13:14:54 -0000	1.16
  +++ DefaultDeploymentModel.java	24 Jul 2003 22:14:55 -0000	1.17
  @@ -64,7 +64,9 @@
   import org.apache.avalon.composition.model.ClassLoaderModel;
   import org.apache.avalon.composition.model.ModelException;
   import org.apache.avalon.composition.model.SystemContext;
  +import org.apache.avalon.composition.model.StageModel;
   import org.apache.avalon.composition.data.DependencyDirective;
  +import org.apache.avalon.composition.data.StageDirective;
   import org.apache.avalon.composition.repository.Repository;
   import org.apache.avalon.excalibur.i18n.ResourceManager;
   import org.apache.avalon.excalibur.i18n.Resources;
  @@ -120,6 +122,8 @@
   
       private final DependencyModel[] m_dependencies;
   
  +    private final StageModel[] m_stages;
  +
       //==============================================================
       // mutable state
       //==============================================================
  @@ -230,6 +234,29 @@
                   descriptor,
                   directive );
           }
  +
  +        //
  +        // create the stage models for subsequent assembly
  +        // management
  +        //
  +
  +        StageDescriptor[] stages = 
  +          m_context.getType().getStages();
  +        m_stages = new DefaultStageModel[ stages.length ];
  +
  +        for( int i=0; i<stages.length; i++ )
  +        {
  +            StageDescriptor descriptor = stages[i];
  +            StageDirective directive = 
  +              context.getProfile().getStageDirective( descriptor.getKey() );
  +            m_stages[i] = 
  +              new DefaultStageModel( 
  +                context.getLogger().getChildLogger( "stages" ), 
  +                context.getPartitionName(), 
  +                context.getProfile().getName(), 
  +                descriptor,
  +                directive );
  +        }
       }
   
       //==============================================================
  @@ -517,15 +544,24 @@
       }
   
      /**
  -    * Return the dependency model for this component type.
  +    * Return the dependency models for this component type.
       *
  -    * @return the dependency model
  +    * @return the dependency models
       */
       public DependencyModel[] getDependencyModels()
       {
           return m_dependencies;
       }
   
  +   /**
  +    * Return the stage models for this component type.
  +    *
  +    * @return the stage models
  +    */
  +    public StageModel[] getStageModels()
  +    {
  +        return m_stages;
  +    }
   
       //==============================================================
       // implementation
  
  
  
  1.1                  avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/DefaultStageModel.java
  
  Index: DefaultStageModel.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Jakarta", "Apache Avalon", "Avalon Framework" and
      "Apache Software Foundation"  must not be used to endorse or promote
      products derived  from this  software without  prior written
      permission. For written permission, please contact apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation. For more  information on the
   Apache Software Foundation, please see <http://www.apache.org/>.
  
  */
  
  package org.apache.avalon.composition.model.impl;
  
  import java.io.File;
  import java.util.ArrayList;
  import java.util.Enumeration;
  import java.util.Properties;
  import java.util.Hashtable;
  import java.util.Map;
  
  import org.apache.avalon.composition.model.DeploymentContext;
  import org.apache.avalon.composition.model.StageModel;
  import org.apache.avalon.composition.model.Model;
  import org.apache.avalon.composition.model.ModelException;
  import org.apache.avalon.composition.data.StageDirective;
  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.StageDescriptor;
  import org.apache.avalon.meta.info.ExtensionDescriptor;
  
  /**
   * Default implementation of the stage model.
   *
   * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
   * @version $Revision: 1.1 $ $Date: 2003/07/24 22:14:55 $
   */
  public class DefaultStageModel extends AbstractLogEnabled implements StageModel
  {
      //==============================================================
      // static
      //==============================================================
  
      private static final Resources REZ =
              ResourceManager.getPackageResources( DefaultDependencyModel.class );
  
      //==============================================================
      // immutable state
      //==============================================================
  
      private final StageDescriptor m_descriptor;
  
      private final StageDirective m_directive;
  
      private final String m_partition;
  
      private final String m_name;
  
      private final String m_source;
  
      //==============================================================
      // constructor
      //==============================================================
  
     /**
      * Creation of a new stage model.
      *
      * @param logger the logging channel
      * @param descriptors the dependency descriptors
      * @param directives the dependency directives (possibly null)
      */
      public DefaultStageModel( 
        final Logger logger, final String partition, final String name, 
        final StageDescriptor descriptor, StageDirective directive )
        throws ModelException
      {
          if( logger == null ) throw new NullPointerException( "logger" );
          if( descriptor == null ) throw new NullPointerException( "descriptor" );
  
          enableLogging( logger );
          m_descriptor = descriptor;
          m_directive = directive;
          m_partition = partition;
          m_name = name;
  
          //
          // a stage directive is either declaring with an explicitly
          // identified provider, or, it is delcaring 0 or more selection 
          // constraints - if its an absolute source declaration then 
          // resolve it now
          //
  
          if( directive != null )
          {
              if( directive.getSource() != null )
              {
                  m_source = resolvePath( partition, directive.getSource() );
                  final String message =
                    REZ.getString( "dependency.path.debug", m_source, directive.getKey() );
                  getLogger().debug( message );
              }
              else
              {
                  m_source = null;
              }
          }
          else
          {
              m_source = null;
          }
      }
  
      //==============================================================
      // StageModel
      //==============================================================
  
     /**
      * Return the stage descriptor.
      *
      * @return the descriptor
      */
      public StageDescriptor getStage()
      {
          return m_descriptor;
      }
  
     /**
      * Return an explicit path to a supplier component.  
      * If a stage 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 dependent component.
      *
      * @return the explicit path
      */
      public String getPath()
      {
          return m_source;
      }
  
     /**
      * Filter a set of candidate extension descriptors and return the 
      * set of acceptable extensions as a ordered sequence.
      *
      * @param candidates the set of candidate stage providers
      * @return the accepted candidates in ranked order
      */
      public ExtensionDescriptor[] filter( ExtensionDescriptor[] candidates ) 
      {
          if( m_directive != null )
          {
              if( m_directive.getSource() == null )
              {
                  return filter( m_directive, candidates );
              }
          }
          return candidates;
      }
  
     /**
      * Filter a set of candidate service descriptors and return the 
      * set of acceptable stage providers 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 ExtensionDescriptor[] filter( 
        StageDirective directive, ExtensionDescriptor[] providers ) 
      {
          SelectionDirective[] filters = getFilters( directive );
          ArrayList list = new ArrayList();
  
          for( int i=0; i<providers.length; i++ )
          {
              ExtensionDescriptor provider = providers[i];
              if( isaCandidate( provider, filters ) )
              {
                  list.add( provider );
              }
          }
  
          ExtensionDescriptor[] candidates = 
            (ExtensionDescriptor[]) list.toArray( new ExtensionDescriptor[0] );
  
          //
          // TODO: include ranking of candidates
          //
  
          return candidates;
      }
  
      private boolean isaCandidate( 
        ExtensionDescriptor provider, SelectionDirective[] filters )
      {
          for( int i=0; i<filters.length; i++ )
          {
              SelectionDirective filter = filters[i];
              if( !isaCandidate( provider, filter ) )
              {
                  return false;
              }
          }
          return true;
      }
  
      private boolean isaCandidate( 
        ExtensionDescriptor provider, 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( provider.getAttribute( feature ) );
          }
          else if( criteria.equals( SelectionDirective.EXISTS ) )
          {
              return provider.getAttribute( feature ) != null;
          }
          else if( criteria.equals( SelectionDirective.INCLUDES ) )
          {
              final String v = provider.getAttribute( feature );
              if( v != null )
              {
                  return v.indexOf( value ) > -1;
              }
              else
              {
                  return false;
              }
          }
          else
          {
              final String error = 
                REZ.getString( "stage.invalid-criteria.error", criteria, feature );
              throw new IllegalArgumentException( error );
          }
      }
  
      private String resolvePath( String partition, String path )
      {
          if( path.startsWith( "/" ) )
          {
              return path;
          }
          else if( path.startsWith( "../" ) )
          {
              final String parent = getParentPath( partition );
              return resolvePath( parent, path.substring( 3 ) );
          }
          else if( path.startsWith( "./" ) )
          {
              return resolvePath( partition, path.substring( 2 ) );
          }
          else
          {
              return partition + path;
          }
      }
  
      private String getParentPath( String partition )
      {
          int n = partition.lastIndexOf( "/" );
          if( n > 0 )
          {
              int index = partition.substring( 0, n-1 ).lastIndexOf( "/" );
              if( index == 0 )
              {
                  return "/";
              }
              else
              {
                  return partition.substring( 0, index );
              }
          }
          else
          {
              final String error = 
                "Illegal attempt to reference a containment context above the root context.";
              throw new IllegalArgumentException( error );
          }
      }
  
     /**
      * Return the required selection constraints.
      * @param directive the dependency directive
      * @return the set of required selection directives
      */
      private SelectionDirective[] getFilters( StageDirective 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.2       +4 -1      avalon-sandbox/merlin/composition/src/test/org/apache/avalon/composition/data/test/DeploymentProfileTestCase.java
  
  Index: DeploymentProfileTestCase.java
  ===================================================================
  RCS file: /home/cvs/avalon-sandbox/merlin/composition/src/test/org/apache/avalon/composition/data/test/DeploymentProfileTestCase.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- DeploymentProfileTestCase.java	17 Jul 2003 21:21:58 -0000	1.1
  +++ DeploymentProfileTestCase.java	24 Jul 2003 22:14:55 -0000	1.2
  @@ -78,6 +78,7 @@
       private Configuration m_configuration;
       private ContextDirective m_context;
       private DependencyDirective[] m_dependencies;
  +    private StageDirective[] m_stages;
       private String m_name;
       private String m_classname;
   
  @@ -94,6 +95,7 @@
             new ContextDirective( getClass().getName(), new ImportDirective[0] );
           m_configuration = new DefaultConfiguration("test");
           m_dependencies = new DependencyDirective[0];
  +        m_stages = new StageDirective[0];
           m_parameters = Parameters.fromProperties(System.getProperties());
           m_activation = true;
           m_mode = Mode.IMPLICIT;
  @@ -104,7 +106,8 @@
       {
           DeploymentProfile profile = new DeploymentProfile(
             m_name, m_activation, m_classname, m_categories, 
  -          m_context, m_dependencies, m_parameters, m_configuration, m_mode );
  +          m_context, m_dependencies, m_stages, m_parameters, 
  +          m_configuration, m_mode );
   
           assertEquals( "name", m_name, profile.getName() );
           assertEquals( "classname", m_classname, profile.getClassname() );
  
  
  

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